diff --git a/bin/boot_v1.6.bin b/bin/boot_v1.6.bin old mode 100755 new mode 100644 diff --git a/bin/esp_init_data_default.bin b/bin/esp_init_data_default.bin old mode 100755 new mode 100644 diff --git a/driver_lib/Makefile b/driver_lib/Makefile old mode 100755 new mode 100644 diff --git a/driver_lib/README.md b/driver_lib/README.md old mode 100755 new mode 100644 diff --git a/driver_lib/driver/Makefile b/driver_lib/driver/Makefile index 5b8f77a4..ff6a9afb 100644 --- a/driver_lib/driver/Makefile +++ b/driver_lib/driver/Makefile @@ -1,43 +1,43 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR -GEN_LIBS = libdriver.a -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +GEN_LIBS = libdriver.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/driver_lib/driver/hw_timer.c b/driver_lib/driver/hw_timer.c index 9193539a..95529715 100644 --- a/driver_lib/driver/hw_timer.c +++ b/driver_lib/driver/hw_timer.c @@ -1,116 +1,116 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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. - * - */ - -#include "esp_common.h" - -#define US_TO_RTC_TIMER_TICKS(t) \ - ((t) ? \ - (((t) > 0x35A) ? \ - (((t) >> 2) * ((APB_CLK_FREQ >> 4) / 250000) + ((t)&0x3) * ((APB_CLK_FREQ >> 4) / 1000000)) : \ - (((t) *(APB_CLK_FREQ>>4)) / 1000000)) : \ - 0) - -#define FRC1_ENABLE_TIMER BIT7 -#define FRC1_AUTO_LOAD BIT6 - -typedef enum { // timer provided mode - DIVDED_BY_1 = 0, // timer clock - DIVDED_BY_16 = 4, // divided by 16 - DIVDED_BY_256 = 8, // divided by 256 -} TIMER_PREDIVED_MODE; - -typedef enum { // timer interrupt mode - TM_LEVEL_INT = 1, // level interrupt - TM_EDGE_INT = 0, // edge interrupt -} TIMER_INT_MODE; - -#define RTC_REG_WRITE(addr, val) WRITE_PERI_REG(addr, val) - -static void (* user_hw_timer_cb)(void) = NULL; - -static void hw_timer_isr_cb(void *arg) -{ - if (user_hw_timer_cb != NULL) { - (*(user_hw_timer_cb))(); - } -} - -void hw_timer_arm(uint32 val) -{ - RTC_REG_WRITE(FRC1_LOAD_ADDRESS, US_TO_RTC_TIMER_TICKS(val)); -} - -void hw_timer_set_func(void (* user_hw_timer_cb_set)(void)) -{ - user_hw_timer_cb = user_hw_timer_cb_set; -} - -void hw_timer_init(uint8 req) -{ - if (req == 1) { - RTC_REG_WRITE(FRC1_CTRL_ADDRESS, - FRC1_AUTO_LOAD | DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT); - } else { - RTC_REG_WRITE(FRC1_CTRL_ADDRESS, - DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT); - } - - _xt_isr_attach(ETS_FRC_TIMER1_INUM, hw_timer_isr_cb, NULL); - - TM1_EDGE_INT_ENABLE(); - _xt_isr_unmask(1 << ETS_FRC_TIMER1_INUM); -} - -//-------------------------------Test Code Below-------------------------------------- -#if 0 -#include "hw_timer.h" - -#define REG_WRITE(_r,_v) (*(volatile uint32 *)(_r)) = (_v) -#define REG_READ(_r) (*(volatile uint32 *)(_r)) -#define WDEV_NOW() REG_READ(0x3ff20c00) - -uint32 tick_now2 = 0; -void hw_test_timer_cb(void) -{ - static uint16 j = 0; - j++; - - if ((WDEV_NOW() - tick_now2) >= 1000000) { - static uint32 idx = 1; - tick_now2 = WDEV_NOW(); - os_printf("b%u:%d\n", idx++, j); - j = 0; - } - - //hw_timer_arm(50); -} - -void user_init(void) -{ - hw_timer_init(1); - hw_timer_set_func(hw_test_timer_cb); - hw_timer_arm(100); -} -#endif - +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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. + * + */ + +#include "esp_common.h" + +#define US_TO_RTC_TIMER_TICKS(t) \ + ((t) ? \ + (((t) > 0x35A) ? \ + (((t) >> 2) * ((APB_CLK_FREQ >> 4) / 250000) + ((t)&0x3) * ((APB_CLK_FREQ >> 4) / 1000000)) : \ + (((t) *(APB_CLK_FREQ>>4)) / 1000000)) : \ + 0) + +#define FRC1_ENABLE_TIMER BIT7 +#define FRC1_AUTO_LOAD BIT6 + +typedef enum { // timer provided mode + DIVDED_BY_1 = 0, // timer clock + DIVDED_BY_16 = 4, // divided by 16 + DIVDED_BY_256 = 8, // divided by 256 +} TIMER_PREDIVED_MODE; + +typedef enum { // timer interrupt mode + TM_LEVEL_INT = 1, // level interrupt + TM_EDGE_INT = 0, // edge interrupt +} TIMER_INT_MODE; + +#define RTC_REG_WRITE(addr, val) WRITE_PERI_REG(addr, val) + +static void (* user_hw_timer_cb)(void) = NULL; + +static void hw_timer_isr_cb(void *arg) +{ + if (user_hw_timer_cb != NULL) { + (*(user_hw_timer_cb))(); + } +} + +void hw_timer_arm(uint32 val) +{ + RTC_REG_WRITE(FRC1_LOAD_ADDRESS, US_TO_RTC_TIMER_TICKS(val)); +} + +void hw_timer_set_func(void (* user_hw_timer_cb_set)(void)) +{ + user_hw_timer_cb = user_hw_timer_cb_set; +} + +void hw_timer_init(uint8 req) +{ + if (req == 1) { + RTC_REG_WRITE(FRC1_CTRL_ADDRESS, + FRC1_AUTO_LOAD | DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT); + } else { + RTC_REG_WRITE(FRC1_CTRL_ADDRESS, + DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT); + } + + _xt_isr_attach(ETS_FRC_TIMER1_INUM, hw_timer_isr_cb, NULL); + + TM1_EDGE_INT_ENABLE(); + _xt_isr_unmask(1 << ETS_FRC_TIMER1_INUM); +} + +//-------------------------------Test Code Below-------------------------------------- +#if 0 +#include "hw_timer.h" + +#define REG_WRITE(_r,_v) (*(volatile uint32 *)(_r)) = (_v) +#define REG_READ(_r) (*(volatile uint32 *)(_r)) +#define WDEV_NOW() REG_READ(0x3ff20c00) + +uint32 tick_now2 = 0; +void hw_test_timer_cb(void) +{ + static uint16 j = 0; + j++; + + if ((WDEV_NOW() - tick_now2) >= 1000000) { + static uint32 idx = 1; + tick_now2 = WDEV_NOW(); + os_printf("b%u:%d\n", idx++, j); + j = 0; + } + + //hw_timer_arm(50); +} + +void user_init(void) +{ + hw_timer_init(1); + hw_timer_set_func(hw_test_timer_cb); + hw_timer_arm(100); +} +#endif + diff --git a/driver_lib/driver/i2c_master.c b/driver_lib/driver/i2c_master.c old mode 100755 new mode 100644 index b38aed57..c3176a70 --- a/driver_lib/driver/i2c_master.c +++ b/driver_lib/driver/i2c_master.c @@ -1,319 +1,319 @@ -/****************************************************************************** - * Copyright 2013-2014 Espressif Systems (Wuxi) - * - * FileName: i2c_master.c - * - * Description: i2c master API - * - * Modification history: - * 2014/3/12, v1.0 create this file. -*******************************************************************************/ -#include "c_types.h" -#include "esp8266/ets_sys.h" -#include "gpio.h" - -#include "i2c_master.h" - -LOCAL uint8 m_nLastSDA; -LOCAL uint8 m_nLastSCL; - -/****************************************************************************** - * FunctionName : i2c_master_setDC - * Description : Internal used function - - * set i2c SDA and SCL bit value for half clk cycle - * Parameters : uint8 SDA - * uint8 SCL - * Returns : NONE -*******************************************************************************/ -LOCAL void ICACHE_FLASH_ATTR -i2c_master_setDC(uint8 SDA, uint8 SCL) -{ - SDA &= 0x01; - SCL &= 0x01; - m_nLastSDA = SDA; - m_nLastSCL = SCL; - ETS_INTR_LOCK(); - if ((0 == SDA) && (0 == SCL)) { - I2C_MASTER_SDA_LOW_SCL_LOW(); - } else if ((0 == SDA) && (1 == SCL)) { - I2C_MASTER_SDA_LOW_SCL_HIGH(); - } else if ((1 == SDA) && (0 == SCL)) { - I2C_MASTER_SDA_HIGH_SCL_LOW(); - } else { - I2C_MASTER_SDA_HIGH_SCL_HIGH(); - } - ETS_INTR_UNLOCK(); -} - -/****************************************************************************** - * FunctionName : i2c_master_getDC - * Description : Internal used function - - * get i2c SDA bit value - * Parameters : NONE - * Returns : uint8 - SDA bit value -*******************************************************************************/ -LOCAL uint8 ICACHE_FLASH_ATTR -i2c_master_getDC(void) -{ - uint8 sda_out; - ETS_INTR_LOCK(); - sda_out = GPIO_INPUT_GET(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO)); - ETS_INTR_UNLOCK(); - return sda_out; -} - -/****************************************************************************** - * FunctionName : i2c_master_init - * Description : initilize I2C bus to enable i2c operations - * Parameters : NONE - * Returns : NONE -*******************************************************************************/ -void ICACHE_FLASH_ATTR -i2c_master_init(void) -{ - uint8 i; - - i2c_master_setDC(1, 0); - i2c_master_wait(5); - - // when SCL = 0, toggle SDA to clear up - i2c_master_setDC(0, 0) ; - i2c_master_wait(5); - i2c_master_setDC(1, 0) ; - i2c_master_wait(5); - - // set data_cnt to max value - for (i = 0; i < 28; i++) { - i2c_master_setDC(1, 0); - i2c_master_wait(5); // sda 1, scl 0 - i2c_master_setDC(1, 1); - i2c_master_wait(5); // sda 1, scl 1 - } - - // reset all - i2c_master_stop(); - return; -} - -/****************************************************************************** - * FunctionName : i2c_master_gpio_init - * Description : config SDA and SCL gpio to open-drain output mode, - * mux and gpio num defined in i2c_master.h - * Parameters : NONE - * Returns : NONE -*******************************************************************************/ -void ICACHE_FLASH_ATTR -i2c_master_gpio_init(void) -{ - ETS_GPIO_INTR_DISABLE() ; -// ETS_INTR_LOCK(); - - PIN_FUNC_SELECT(I2C_MASTER_SDA_MUX, I2C_MASTER_SDA_FUNC); - PIN_FUNC_SELECT(I2C_MASTER_SCL_MUX, I2C_MASTER_SCL_FUNC); - - GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO)), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)); //open drain; - GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_MASTER_SDA_GPIO)); - GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SCL_GPIO)), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SCL_GPIO))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)); //open drain; - GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_MASTER_SCL_GPIO)); - - I2C_MASTER_SDA_HIGH_SCL_HIGH(); - - ETS_GPIO_INTR_ENABLE() ; -// ETS_INTR_UNLOCK(); - - i2c_master_init(); -} - -/****************************************************************************** - * FunctionName : i2c_master_start - * Description : set i2c to send state - * Parameters : NONE - * Returns : NONE -*******************************************************************************/ -void ICACHE_FLASH_ATTR -i2c_master_start(void) -{ - i2c_master_setDC(1, m_nLastSCL); - i2c_master_wait(5); - i2c_master_setDC(1, 1); - i2c_master_wait(5); // sda 1, scl 1 - i2c_master_setDC(0, 1); - i2c_master_wait(5); // sda 0, scl 1 -} - -/****************************************************************************** - * FunctionName : i2c_master_stop - * Description : set i2c to stop sending state - * Parameters : NONE - * Returns : NONE -*******************************************************************************/ -void ICACHE_FLASH_ATTR -i2c_master_stop(void) -{ - i2c_master_wait(5); - - i2c_master_setDC(0, m_nLastSCL); - i2c_master_wait(5); // sda 0 - i2c_master_setDC(0, 1); - i2c_master_wait(5); // sda 0, scl 1 - i2c_master_setDC(1, 1); - i2c_master_wait(5); // sda 1, scl 1 -} - -/****************************************************************************** - * FunctionName : i2c_master_setAck - * Description : set ack to i2c bus as level value - * Parameters : uint8 level - 0 or 1 - * Returns : NONE -*******************************************************************************/ -void ICACHE_FLASH_ATTR -i2c_master_setAck(uint8 level) -{ - i2c_master_setDC(m_nLastSDA, 0); - i2c_master_wait(5); - i2c_master_setDC(level, 0); - i2c_master_wait(5); // sda level, scl 0 - i2c_master_setDC(level, 1); - i2c_master_wait(8); // sda level, scl 1 - i2c_master_setDC(level, 0); - i2c_master_wait(5); // sda level, scl 0 - i2c_master_setDC(1, 0); - i2c_master_wait(5); -} - -/****************************************************************************** - * FunctionName : i2c_master_getAck - * Description : confirm if peer send ack - * Parameters : NONE - * Returns : uint8 - ack value, 0 or 1 -*******************************************************************************/ -uint8 ICACHE_FLASH_ATTR -i2c_master_getAck(void) -{ - uint8 retVal; - i2c_master_setDC(m_nLastSDA, 0); - i2c_master_wait(5); - i2c_master_setDC(1, 0); - i2c_master_wait(5); - i2c_master_setDC(1, 1); - i2c_master_wait(5); - - retVal = i2c_master_getDC(); - i2c_master_wait(5); - i2c_master_setDC(1, 0); - i2c_master_wait(5); - - return retVal; -} - -/****************************************************************************** -* FunctionName : i2c_master_checkAck -* Description : get dev response -* Parameters : NONE -* Returns : true : get ack ; false : get nack -*******************************************************************************/ -bool ICACHE_FLASH_ATTR -i2c_master_checkAck(void) -{ - if(i2c_master_getAck()){ - return FALSE; - }else{ - return TRUE; - } -} - -/****************************************************************************** -* FunctionName : i2c_master_send_ack -* Description : response ack -* Parameters : NONE -* Returns : NONE -*******************************************************************************/ -void ICACHE_FLASH_ATTR -i2c_master_send_ack(void) -{ - i2c_master_setAck(0x0); -} -/****************************************************************************** -* FunctionName : i2c_master_send_nack -* Description : response nack -* Parameters : NONE -* Returns : NONE -*******************************************************************************/ -void ICACHE_FLASH_ATTR -i2c_master_send_nack(void) -{ - i2c_master_setAck(0x1); -} - -/****************************************************************************** - * FunctionName : i2c_master_readByte - * Description : read Byte from i2c bus - * Parameters : NONE - * Returns : uint8 - readed value -*******************************************************************************/ -uint8 ICACHE_FLASH_ATTR -i2c_master_readByte(void) -{ - uint8 retVal = 0; - uint8 k, i; - - i2c_master_wait(5); - i2c_master_setDC(m_nLastSDA, 0); - i2c_master_wait(5); // sda 1, scl 0 - - for (i = 0; i < 8; i++) { - i2c_master_wait(5); - i2c_master_setDC(1, 0); - i2c_master_wait(5); // sda 1, scl 0 - i2c_master_setDC(1, 1); - i2c_master_wait(5); // sda 1, scl 1 - - k = i2c_master_getDC(); - i2c_master_wait(5); - - if (i == 7) { - i2c_master_wait(3); //// - } - - k <<= (7 - i); - retVal |= k; - } - - i2c_master_setDC(1, 0); - i2c_master_wait(5); // sda 1, scl 0 - - return retVal; -} - -/****************************************************************************** - * FunctionName : i2c_master_writeByte - * Description : write wrdata value(one byte) into i2c - * Parameters : uint8 wrdata - write value - * Returns : NONE -*******************************************************************************/ -void ICACHE_FLASH_ATTR -i2c_master_writeByte(uint8 wrdata) -{ - uint8 dat; - sint8 i; - - i2c_master_wait(5); - - i2c_master_setDC(m_nLastSDA, 0); - i2c_master_wait(5); - - for (i = 7; i >= 0; i--) { - dat = wrdata >> i; - i2c_master_setDC(dat, 0); - i2c_master_wait(5); - i2c_master_setDC(dat, 1); - i2c_master_wait(5); - - if (i == 0) { - i2c_master_wait(3); //// - } - - i2c_master_setDC(dat, 0); - i2c_master_wait(5); - } -} +/****************************************************************************** + * Copyright 2013-2014 Espressif Systems (Wuxi) + * + * FileName: i2c_master.c + * + * Description: i2c master API + * + * Modification history: + * 2014/3/12, v1.0 create this file. +*******************************************************************************/ +#include "c_types.h" +#include "esp8266/ets_sys.h" +#include "gpio.h" + +#include "i2c_master.h" + +LOCAL uint8 m_nLastSDA; +LOCAL uint8 m_nLastSCL; + +/****************************************************************************** + * FunctionName : i2c_master_setDC + * Description : Internal used function - + * set i2c SDA and SCL bit value for half clk cycle + * Parameters : uint8 SDA + * uint8 SCL + * Returns : NONE +*******************************************************************************/ +LOCAL void ICACHE_FLASH_ATTR +i2c_master_setDC(uint8 SDA, uint8 SCL) +{ + SDA &= 0x01; + SCL &= 0x01; + m_nLastSDA = SDA; + m_nLastSCL = SCL; + ETS_INTR_LOCK(); + if ((0 == SDA) && (0 == SCL)) { + I2C_MASTER_SDA_LOW_SCL_LOW(); + } else if ((0 == SDA) && (1 == SCL)) { + I2C_MASTER_SDA_LOW_SCL_HIGH(); + } else if ((1 == SDA) && (0 == SCL)) { + I2C_MASTER_SDA_HIGH_SCL_LOW(); + } else { + I2C_MASTER_SDA_HIGH_SCL_HIGH(); + } + ETS_INTR_UNLOCK(); +} + +/****************************************************************************** + * FunctionName : i2c_master_getDC + * Description : Internal used function - + * get i2c SDA bit value + * Parameters : NONE + * Returns : uint8 - SDA bit value +*******************************************************************************/ +LOCAL uint8 ICACHE_FLASH_ATTR +i2c_master_getDC(void) +{ + uint8 sda_out; + ETS_INTR_LOCK(); + sda_out = GPIO_INPUT_GET(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO)); + ETS_INTR_UNLOCK(); + return sda_out; +} + +/****************************************************************************** + * FunctionName : i2c_master_init + * Description : initilize I2C bus to enable i2c operations + * Parameters : NONE + * Returns : NONE +*******************************************************************************/ +void ICACHE_FLASH_ATTR +i2c_master_init(void) +{ + uint8 i; + + i2c_master_setDC(1, 0); + i2c_master_wait(5); + + // when SCL = 0, toggle SDA to clear up + i2c_master_setDC(0, 0) ; + i2c_master_wait(5); + i2c_master_setDC(1, 0) ; + i2c_master_wait(5); + + // set data_cnt to max value + for (i = 0; i < 28; i++) { + i2c_master_setDC(1, 0); + i2c_master_wait(5); // sda 1, scl 0 + i2c_master_setDC(1, 1); + i2c_master_wait(5); // sda 1, scl 1 + } + + // reset all + i2c_master_stop(); + return; +} + +/****************************************************************************** + * FunctionName : i2c_master_gpio_init + * Description : config SDA and SCL gpio to open-drain output mode, + * mux and gpio num defined in i2c_master.h + * Parameters : NONE + * Returns : NONE +*******************************************************************************/ +void ICACHE_FLASH_ATTR +i2c_master_gpio_init(void) +{ + ETS_GPIO_INTR_DISABLE() ; +// ETS_INTR_LOCK(); + + PIN_FUNC_SELECT(I2C_MASTER_SDA_MUX, I2C_MASTER_SDA_FUNC); + PIN_FUNC_SELECT(I2C_MASTER_SCL_MUX, I2C_MASTER_SCL_FUNC); + + GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO)), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)); //open drain; + GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_MASTER_SDA_GPIO)); + GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SCL_GPIO)), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(I2C_MASTER_SCL_GPIO))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)); //open drain; + GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << I2C_MASTER_SCL_GPIO)); + + I2C_MASTER_SDA_HIGH_SCL_HIGH(); + + ETS_GPIO_INTR_ENABLE() ; +// ETS_INTR_UNLOCK(); + + i2c_master_init(); +} + +/****************************************************************************** + * FunctionName : i2c_master_start + * Description : set i2c to send state + * Parameters : NONE + * Returns : NONE +*******************************************************************************/ +void ICACHE_FLASH_ATTR +i2c_master_start(void) +{ + i2c_master_setDC(1, m_nLastSCL); + i2c_master_wait(5); + i2c_master_setDC(1, 1); + i2c_master_wait(5); // sda 1, scl 1 + i2c_master_setDC(0, 1); + i2c_master_wait(5); // sda 0, scl 1 +} + +/****************************************************************************** + * FunctionName : i2c_master_stop + * Description : set i2c to stop sending state + * Parameters : NONE + * Returns : NONE +*******************************************************************************/ +void ICACHE_FLASH_ATTR +i2c_master_stop(void) +{ + i2c_master_wait(5); + + i2c_master_setDC(0, m_nLastSCL); + i2c_master_wait(5); // sda 0 + i2c_master_setDC(0, 1); + i2c_master_wait(5); // sda 0, scl 1 + i2c_master_setDC(1, 1); + i2c_master_wait(5); // sda 1, scl 1 +} + +/****************************************************************************** + * FunctionName : i2c_master_setAck + * Description : set ack to i2c bus as level value + * Parameters : uint8 level - 0 or 1 + * Returns : NONE +*******************************************************************************/ +void ICACHE_FLASH_ATTR +i2c_master_setAck(uint8 level) +{ + i2c_master_setDC(m_nLastSDA, 0); + i2c_master_wait(5); + i2c_master_setDC(level, 0); + i2c_master_wait(5); // sda level, scl 0 + i2c_master_setDC(level, 1); + i2c_master_wait(8); // sda level, scl 1 + i2c_master_setDC(level, 0); + i2c_master_wait(5); // sda level, scl 0 + i2c_master_setDC(1, 0); + i2c_master_wait(5); +} + +/****************************************************************************** + * FunctionName : i2c_master_getAck + * Description : confirm if peer send ack + * Parameters : NONE + * Returns : uint8 - ack value, 0 or 1 +*******************************************************************************/ +uint8 ICACHE_FLASH_ATTR +i2c_master_getAck(void) +{ + uint8 retVal; + i2c_master_setDC(m_nLastSDA, 0); + i2c_master_wait(5); + i2c_master_setDC(1, 0); + i2c_master_wait(5); + i2c_master_setDC(1, 1); + i2c_master_wait(5); + + retVal = i2c_master_getDC(); + i2c_master_wait(5); + i2c_master_setDC(1, 0); + i2c_master_wait(5); + + return retVal; +} + +/****************************************************************************** +* FunctionName : i2c_master_checkAck +* Description : get dev response +* Parameters : NONE +* Returns : true : get ack ; false : get nack +*******************************************************************************/ +bool ICACHE_FLASH_ATTR +i2c_master_checkAck(void) +{ + if(i2c_master_getAck()){ + return FALSE; + }else{ + return TRUE; + } +} + +/****************************************************************************** +* FunctionName : i2c_master_send_ack +* Description : response ack +* Parameters : NONE +* Returns : NONE +*******************************************************************************/ +void ICACHE_FLASH_ATTR +i2c_master_send_ack(void) +{ + i2c_master_setAck(0x0); +} +/****************************************************************************** +* FunctionName : i2c_master_send_nack +* Description : response nack +* Parameters : NONE +* Returns : NONE +*******************************************************************************/ +void ICACHE_FLASH_ATTR +i2c_master_send_nack(void) +{ + i2c_master_setAck(0x1); +} + +/****************************************************************************** + * FunctionName : i2c_master_readByte + * Description : read Byte from i2c bus + * Parameters : NONE + * Returns : uint8 - readed value +*******************************************************************************/ +uint8 ICACHE_FLASH_ATTR +i2c_master_readByte(void) +{ + uint8 retVal = 0; + uint8 k, i; + + i2c_master_wait(5); + i2c_master_setDC(m_nLastSDA, 0); + i2c_master_wait(5); // sda 1, scl 0 + + for (i = 0; i < 8; i++) { + i2c_master_wait(5); + i2c_master_setDC(1, 0); + i2c_master_wait(5); // sda 1, scl 0 + i2c_master_setDC(1, 1); + i2c_master_wait(5); // sda 1, scl 1 + + k = i2c_master_getDC(); + i2c_master_wait(5); + + if (i == 7) { + i2c_master_wait(3); //// + } + + k <<= (7 - i); + retVal |= k; + } + + i2c_master_setDC(1, 0); + i2c_master_wait(5); // sda 1, scl 0 + + return retVal; +} + +/****************************************************************************** + * FunctionName : i2c_master_writeByte + * Description : write wrdata value(one byte) into i2c + * Parameters : uint8 wrdata - write value + * Returns : NONE +*******************************************************************************/ +void ICACHE_FLASH_ATTR +i2c_master_writeByte(uint8 wrdata) +{ + uint8 dat; + sint8 i; + + i2c_master_wait(5); + + i2c_master_setDC(m_nLastSDA, 0); + i2c_master_wait(5); + + for (i = 7; i >= 0; i--) { + dat = wrdata >> i; + i2c_master_setDC(dat, 0); + i2c_master_wait(5); + i2c_master_setDC(dat, 1); + i2c_master_wait(5); + + if (i == 0) { + i2c_master_wait(3); //// + } + + i2c_master_setDC(dat, 0); + i2c_master_wait(5); + } +} diff --git a/driver_lib/driver/spi_interface.c b/driver_lib/driver/spi_interface.c old mode 100755 new mode 100644 index dabbabb6..0e8b81de --- a/driver_lib/driver/spi_interface.c +++ b/driver_lib/driver/spi_interface.c @@ -1,509 +1,509 @@ -/** - * spi_interface.c - * - * Defines and Macros for the SPI. - * - * Copyright @ 2015 Espressif System Co., Ltd. - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are NOT permitted except as agreed by - * Espressif System Co., Ltd. - * - * 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. - */ -/** - * @file spi_interface.c - * @brief Defines and Macros for the SPI. - */ - -#include "spi_interface.h" -#include "esp8266/eagle_soc.h" -#include "esp8266/ets_sys.h" -#include "esp_libc.h" -//***************************************************************************** -// -// Make sure all of the definitions in this header have a C binding. -// -//***************************************************************************** -#ifdef __cplusplus -extern "C" -{ -#endif - -// Show the spi registers. -#define SHOWDEBUG - -void __ShowRegValue(const char * func, uint32_t line) -{ -#ifndef SHOWDEBUG - int i; - uint32_t regAddr = 0x60000140; // SPI--0x60000240, HSPI--0x60000140; - printf("\r\n FUNC[%s],line[%d]\r\n", func, line); - printf(" SPI_ADDR [0x%08x]\r\n", READ_PERI_REG(SPI_ADDR(SpiNum_HSPI))); - printf(" SPI_CMD [0x%08x]\r\n", READ_PERI_REG(SPI_CMD(SpiNum_HSPI))); - printf(" SPI_CTRL [0x%08x]\r\n", READ_PERI_REG(SPI_CTRL(SpiNum_HSPI))); - printf(" SPI_CTRL2 [0x%08x]\r\n", READ_PERI_REG(SPI_CTRL2(SpiNum_HSPI))); - printf(" SPI_CLOCK [0x%08x]\r\n", READ_PERI_REG(SPI_CLOCK(SpiNum_HSPI))); - printf(" SPI_RD_STATUS [0x%08x]\r\n", READ_PERI_REG(SPI_RD_STATUS(SpiNum_HSPI))); - printf(" SPI_WR_STATUS [0x%08x]\r\n", READ_PERI_REG(SPI_WR_STATUS(SpiNum_HSPI))); - printf(" SPI_USER [0x%08x]\r\n", READ_PERI_REG(SPI_USER(SpiNum_HSPI))); - printf(" SPI_USER1 [0x%08x]\r\n", READ_PERI_REG(SPI_USER1(SpiNum_HSPI))); - printf(" SPI_USER2 [0x%08x]\r\n", READ_PERI_REG(SPI_USER2(SpiNum_HSPI))); - printf(" SPI_PIN [0x%08x]\r\n", READ_PERI_REG(SPI_PIN(SpiNum_HSPI))); - printf(" SPI_SLAVE [0x%08x]\r\n", READ_PERI_REG(SPI_SLAVE(SpiNum_HSPI))); - printf(" SPI_SLAVE1 [0x%08x]\r\n", READ_PERI_REG(SPI_SLAVE1(SpiNum_HSPI))); - printf(" SPI_SLAVE2 [0x%08x]\r\n", READ_PERI_REG(SPI_SLAVE2(SpiNum_HSPI))); - - for (i = 0; i < 16; ++i) { - printf(" ADDR[0x%08x],Value[0x%08x]\r\n", regAddr, READ_PERI_REG(regAddr)); - regAddr += 4; - } -#endif -} - -// Define SPI interrupt enable macro -#define ETS_SPI_INTR_ENABLE() _xt_isr_unmask(1 << ETS_SPI_INUM) - -/** - * @brief Based on pAttr initialize SPI module. - * - */ -void ICACHE_FLASH_ATTR SPIInit(SpiNum spiNum, SpiAttr* pAttr) -{ - if ((spiNum > SpiNum_HSPI) - || (NULL == pAttr)) { - return; - } - // SPI_CPOL & SPI_CPHA - switch (pAttr->subMode) { - case SpiSubMode_1: - CLEAR_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE); - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE); // CHPA_FALLING_EDGE_SAMPLE - break; - case SpiSubMode_2: - SET_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE); - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE); // CHPA_FALLING_EDGE_SAMPLE - break; - case SpiSubMode_3: - SET_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE); - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE); - break; - case SpiSubMode_0: - default: - CLEAR_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE); - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE); - // To do nothing - break; - } - - // SPI bit order - if (SpiBitOrder_MSBFirst == pAttr->bitOrder) { - CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_WR_BIT_ORDER); - CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_RD_BIT_ORDER); - } else if (SpiBitOrder_LSBFirst == pAttr->bitOrder) { - SET_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_WR_BIT_ORDER); - SET_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_RD_BIT_ORDER); - } else { - // To do nothing - } - - // Disable flash operation mode - // As earlier as better, if not SPI_CTRL2 can not to be set delay cycles. - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_FLASH_MODE); - - // SPI mode type - if (SpiMode_Master == pAttr->mode) { - // SPI mode type - CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), SPI_SLAVE_MODE); - // SPI Send buffer - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO_HIGHPART );// By default slave send buffer C0-C7 - // SPI Speed - if (1 < (pAttr->speed)) { - CLEAR_PERI_REG_MASK(SPI_CLOCK(spiNum), SPI_CLK_EQU_SYSCLK); - WRITE_PERI_REG(SPI_CLOCK(spiNum), - ((pAttr->speed & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) | - ((((pAttr->speed + 1) / 2 - 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) | - ((pAttr->speed & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div - } else { - WRITE_PERI_REG(SPI_CLOCK(spiNum), SPI_CLK_EQU_SYSCLK); // 80Mhz speed - } - // By default format:CMD+ADDR+DATA - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_CS_SETUP | SPI_CS_HOLD | SPI_USR_MOSI ); - - //delay num - SET_PERI_REG_MASK(SPI_CTRL2(spiNum), ((0x1 & SPI_MISO_DELAY_NUM) << SPI_MISO_DELAY_NUM_S)); - } else if (SpiMode_Slave == pAttr->mode) { - // BIT19 must do - SET_PERI_REG_MASK(SPI_PIN(spiNum), BIT19); - - // SPI mode type - SET_PERI_REG_MASK(SPI_SLAVE(spiNum), SPI_SLAVE_MODE); - // SPI Send buffer - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO_HIGHPART);// By default slave send buffer C8-C15 - - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); - - // If do not set delay cycles, slave not working,master cann't get the data. - SET_PERI_REG_MASK(SPI_CTRL2(spiNum), ((0x1 & SPI_MOSI_DELAY_NUM) << SPI_MOSI_DELAY_NUM_S)); //delay num - // SPI Speed - WRITE_PERI_REG(SPI_CLOCK(spiNum), 0); - - // By default format::CMD(8bits)+ADDR(8bits)+DATA(32bytes). - SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN, - 7, SPI_USR_COMMAND_BITLEN_S); - SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_WR_ADDR_BITLEN, - 7, SPI_SLV_WR_ADDR_BITLEN_S); - SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_RD_ADDR_BITLEN, - 7, SPI_SLV_RD_ADDR_BITLEN_S); - SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_BUF_BITLEN, - (32 * 8 - 1), SPI_SLV_BUF_BITLEN_S); - // For 8266 work on slave mode. - SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_STATUS_BITLEN, - 7, SPI_SLV_STATUS_BITLEN_S); - } else { - // To do nothing - } - - //clear Daul or Quad lines transmission mode - CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_QIO_MODE | SPI_DIO_MODE | SPI_DOUT_MODE | SPI_QOUT_MODE); -} - -/** - * @brief Set address value by master mode. - * - */ -void ICACHE_FLASH_ATTR SPIMasterCfgAddr(SpiNum spiNum, uint32_t addr) -{ - if (spiNum > SpiNum_HSPI) { - return; - } - // Set address - WRITE_PERI_REG(SPI_ADDR(spiNum), addr); -} - -/** - * @brief Set command value by master mode. - * - */ -void ICACHE_FLASH_ATTR SPIMasterCfgCmd(SpiNum spiNum, uint32_t cmd) -{ - if (spiNum > SpiNum_HSPI) { - return; - } - // SPI_USER2 bit28-31 is cmd length,cmd bit length is value(0-15)+1, - // bit15-0 is cmd value. - SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_VALUE, cmd, SPI_USR_COMMAND_VALUE_S); -} - -/** - * @brief Send data to slave. - * - */ -int ICACHE_FLASH_ATTR SPIMasterSendData(SpiNum spiNum, SpiData* pInData) -{ - char idx = 0; - if ((spiNum > SpiNum_HSPI) - || (NULL == pInData) - || (64 < pInData->dataLen)) { - return -1; - } - uint32_t *value = pInData->data; - while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); - // Set command by user. - if (pInData->cmdLen != 0) { - // Max command length 16 bits. - SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN, - ((pInData->cmdLen << 3) - 1), SPI_USR_COMMAND_BITLEN_S); - // Enable command - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND); - // Load command - SPIMasterCfgCmd(spiNum, pInData->cmd); - } else { - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND); - SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN, - 0, SPI_USR_COMMAND_BITLEN_S); - } - // Set Address by user. - if (pInData->addrLen == 0) { - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR); - SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN, - 0, SPI_USR_ADDR_BITLEN_S); - } else { - if (NULL == pInData->addr) { - return -1; - } - SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN, - ((pInData->addrLen << 3) - 1), SPI_USR_ADDR_BITLEN_S); - // Enable address - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR); - // Load address - SPIMasterCfgAddr(spiNum, *pInData->addr); - } - // Set data by user. - if (pInData->dataLen != 0) { - if (NULL == value) { - return -1; - } - // Enable MOSI - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO); - // Load send buffer - do { - WRITE_PERI_REG((SPI_W0(spiNum) + (idx << 2)), *value++); - } while (++idx < (pInData->dataLen / 4)); - // Set data send buffer length.Max data length 64 bytes. - SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN, ((pInData->dataLen << 3) - 1), SPI_USR_MOSI_BITLEN_S); - } else { - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); - SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN, - 0, SPI_USR_MOSI_BITLEN_S); - } - // Start send data - SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR); - - SHOWREG(); - return 0; -} - -/** - * @brief Receive data from slave. - * - */ -int ICACHE_FLASH_ATTR SPIMasterRecvData(SpiNum spiNum, SpiData* pOutData) -{ - char idx = 0; - if ((spiNum > SpiNum_HSPI) - || (NULL == pOutData)) { - return -1; - } - - uint32_t *value = pOutData->data; - while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); - // Set command by user. - if (pOutData->cmdLen != 0) { - // Max command length 16 bits. - SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN, - ((pOutData->cmdLen << 3) - 1), SPI_USR_COMMAND_BITLEN_S); - // Enable command - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND); - // Load command - SPIMasterCfgCmd(spiNum, pOutData->cmd); - } else { - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND); - SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN, - 0, SPI_USR_COMMAND_BITLEN_S); - } - // Set Address by user. - if (pOutData->addrLen == 0) { - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR); - SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN, - 0, SPI_USR_ADDR_BITLEN_S); - } else { - if (NULL == pOutData->addr) { - return -1; - } - SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN, - ((pOutData->addrLen << 3) - 1), SPI_USR_ADDR_BITLEN_S); - // Enable address - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR); - // Load address - SPIMasterCfgAddr(spiNum, *pOutData->addr); - } - // Set data by user. - if (pOutData->dataLen != 0) { - if (NULL == value) { - return -1; - } - // Clear MOSI enable - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); - // Enable MOSI - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO); - // Set data send buffer length.Max data length 64 bytes. - SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN, ((pOutData->dataLen << 3) - 1), SPI_USR_MISO_BITLEN_S); - } else { - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO); - SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN, - 0, SPI_USR_MISO_BITLEN_S); - } - // Start send data - SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR); - - while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); - // Read data out - do { - *pOutData->data++ = READ_PERI_REG(SPI_W0(spiNum) + (idx << 2)); - } while (++idx < (pOutData->dataLen / 4)); - - SHOWREG(); - return 0; -} - -/** - * @brief Load data to send buffer by slave mode. - * - */ -int ICACHE_FLASH_ATTR SPISlaveSendData(SpiNum spiNum, uint32_t *pInData, uint8_t outLen) -{ - if (NULL == pInData) { - return -1; - } - char i; - for (i = 0; i < outLen; ++i) { - WRITE_PERI_REG((SPI_W8(spiNum) + (i << 2)), *pInData++); - } - return 0; -} - -/** - * @brief Configurate slave prepare for receive data. - * - */ -int ICACHE_FLASH_ATTR SPISlaveRecvData(SpiNum spiNum, void(*isrFunc)(void*)) -{ - if ((spiNum > SpiNum_HSPI)) { - return -1; - } - - SPIIntEnable(SpiNum_HSPI, SpiIntSrc_WrStaDoneEn - | SpiIntSrc_RdStaDoneEn | SpiIntSrc_WrBufDoneEn | SpiIntSrc_RdBufDoneEn); - SPIIntDisable(SpiNum_HSPI, SpiIntSrc_TransDoneEn); - - // Maybe enable slave transmission liston - SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR); - // - _xt_isr_attach(ETS_SPI_INUM, isrFunc, NULL); - // ETS_SPI_INTR_ATTACH(isrFunc, NULL); - // Enable isr - ETS_SPI_INTR_ENABLE(); - - - SHOWREG(); - - return 0; -} - -/** - * @brief Send data to slave(ESP8266 register of RD_STATUS or WR_STATUS). - * - */ -void ICACHE_FLASH_ATTR SPIMasterSendStatus(SpiNum spiNum, uint8_t data) -{ - if (spiNum > SpiNum_HSPI) { - return; - } - while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); - // Enable MOSI - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR); - - // 8bits cmd, 0x04 is eps8266 slave write cmd value - WRITE_PERI_REG(SPI_USER2(spiNum), - ((7 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) - | MASTER_WRITE_STATUS_TO_SLAVE_CMD); - // Set data send buffer length. - SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN, - ((sizeof(data) << 3) - 1), SPI_USR_MOSI_BITLEN_S); - - WRITE_PERI_REG(SPI_W0(spiNum), (uint32)(data)); - // Start SPI - SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR); - - SHOWREG(); -} - -/** - * @brief Receive status register from slave(ESP8266). - * - */ -int ICACHE_FLASH_ATTR SPIMasterRecvStatus(SpiNum spiNum) -{ - if (spiNum > SpiNum_HSPI) { - return -1; - } - - while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); - // Enable MISO - SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO); - CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI | SPI_USR_DUMMY | SPI_USR_ADDR); - - // 8bits cmd, 0x06 is eps8266 slave read status cmd value - WRITE_PERI_REG(SPI_USER2(spiNum), - ((7 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) - | MASTER_READ_STATUS_FROM_SLAVE_CMD); - // Set revcive buffer length. - SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN, - 7, SPI_USR_MISO_BITLEN_S); - - // start spi module. - SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR); - - while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); - - uint8_t data = (uint8)(READ_PERI_REG(SPI_W0(spiNum)) & 0xff); - SHOWREG(); - - return (uint8)(READ_PERI_REG(SPI_W0(spiNum)) & 0xff); -} - -/** - * @brief Select SPI CS pin. - * - */ -void ICACHE_FLASH_ATTR SPICsPinSelect(SpiNum spiNum, SpiPinCS pinCs) -{ - if (spiNum > SpiNum_HSPI) { - return; - } - // clear select - SET_PERI_REG_BITS(SPI_PIN(spiNum), 3, 0, 0); - SET_PERI_REG_MASK(SPI_PIN(spiNum), pinCs); -} - -/** - * @brief Enable SPI interrupt source. - * - */ -void ICACHE_FLASH_ATTR SPIIntEnable(SpiNum spiNum, SpiIntSrc intSrc) -{ - if (spiNum > SpiNum_HSPI) { - return; - } - SET_PERI_REG_MASK(SPI_SLAVE(spiNum), intSrc); -} - -/** - * @brief Disable SPI interrupt source. - * - */ -void ICACHE_FLASH_ATTR SPIIntDisable(SpiNum spiNum, SpiIntSrc intSrc) -{ - if (spiNum > SpiNum_HSPI) { - return; - } - CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), intSrc); -} - -/** - * @brief Clear all of SPI interrupt source. - * - */ -void ICACHE_FLASH_ATTR SPIIntClear(SpiNum spiNum) -{ - if (spiNum > SpiNum_HSPI) { - return; - } - CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), SpiIntSrc_TransDoneEn - | SpiIntSrc_WrStaDoneEn - | SpiIntSrc_RdStaDoneEn - | SpiIntSrc_WrBufDoneEn - | SpiIntSrc_RdBufDoneEn); -} - - -#ifdef __cplusplus -} +/** + * spi_interface.c + * + * Defines and Macros for the SPI. + * + * Copyright @ 2015 Espressif System Co., Ltd. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are NOT permitted except as agreed by + * Espressif System Co., Ltd. + * + * 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. + */ +/** + * @file spi_interface.c + * @brief Defines and Macros for the SPI. + */ + +#include "spi_interface.h" +#include "esp8266/eagle_soc.h" +#include "esp8266/ets_sys.h" +#include "esp_libc.h" +//***************************************************************************** +// +// Make sure all of the definitions in this header have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +// Show the spi registers. +#define SHOWDEBUG + +void __ShowRegValue(const char * func, uint32_t line) +{ +#ifndef SHOWDEBUG + int i; + uint32_t regAddr = 0x60000140; // SPI--0x60000240, HSPI--0x60000140; + printf("\r\n FUNC[%s],line[%d]\r\n", func, line); + printf(" SPI_ADDR [0x%08x]\r\n", READ_PERI_REG(SPI_ADDR(SpiNum_HSPI))); + printf(" SPI_CMD [0x%08x]\r\n", READ_PERI_REG(SPI_CMD(SpiNum_HSPI))); + printf(" SPI_CTRL [0x%08x]\r\n", READ_PERI_REG(SPI_CTRL(SpiNum_HSPI))); + printf(" SPI_CTRL2 [0x%08x]\r\n", READ_PERI_REG(SPI_CTRL2(SpiNum_HSPI))); + printf(" SPI_CLOCK [0x%08x]\r\n", READ_PERI_REG(SPI_CLOCK(SpiNum_HSPI))); + printf(" SPI_RD_STATUS [0x%08x]\r\n", READ_PERI_REG(SPI_RD_STATUS(SpiNum_HSPI))); + printf(" SPI_WR_STATUS [0x%08x]\r\n", READ_PERI_REG(SPI_WR_STATUS(SpiNum_HSPI))); + printf(" SPI_USER [0x%08x]\r\n", READ_PERI_REG(SPI_USER(SpiNum_HSPI))); + printf(" SPI_USER1 [0x%08x]\r\n", READ_PERI_REG(SPI_USER1(SpiNum_HSPI))); + printf(" SPI_USER2 [0x%08x]\r\n", READ_PERI_REG(SPI_USER2(SpiNum_HSPI))); + printf(" SPI_PIN [0x%08x]\r\n", READ_PERI_REG(SPI_PIN(SpiNum_HSPI))); + printf(" SPI_SLAVE [0x%08x]\r\n", READ_PERI_REG(SPI_SLAVE(SpiNum_HSPI))); + printf(" SPI_SLAVE1 [0x%08x]\r\n", READ_PERI_REG(SPI_SLAVE1(SpiNum_HSPI))); + printf(" SPI_SLAVE2 [0x%08x]\r\n", READ_PERI_REG(SPI_SLAVE2(SpiNum_HSPI))); + + for (i = 0; i < 16; ++i) { + printf(" ADDR[0x%08x],Value[0x%08x]\r\n", regAddr, READ_PERI_REG(regAddr)); + regAddr += 4; + } +#endif +} + +// Define SPI interrupt enable macro +#define ETS_SPI_INTR_ENABLE() _xt_isr_unmask(1 << ETS_SPI_INUM) + +/** + * @brief Based on pAttr initialize SPI module. + * + */ +void ICACHE_FLASH_ATTR SPIInit(SpiNum spiNum, SpiAttr* pAttr) +{ + if ((spiNum > SpiNum_HSPI) + || (NULL == pAttr)) { + return; + } + // SPI_CPOL & SPI_CPHA + switch (pAttr->subMode) { + case SpiSubMode_1: + CLEAR_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE); + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE); // CHPA_FALLING_EDGE_SAMPLE + break; + case SpiSubMode_2: + SET_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE); + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE); // CHPA_FALLING_EDGE_SAMPLE + break; + case SpiSubMode_3: + SET_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE); + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE); + break; + case SpiSubMode_0: + default: + CLEAR_PERI_REG_MASK(SPI_PIN(spiNum), SPI_IDLE_EDGE); + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_CK_OUT_EDGE); + // To do nothing + break; + } + + // SPI bit order + if (SpiBitOrder_MSBFirst == pAttr->bitOrder) { + CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_WR_BIT_ORDER); + CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_RD_BIT_ORDER); + } else if (SpiBitOrder_LSBFirst == pAttr->bitOrder) { + SET_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_WR_BIT_ORDER); + SET_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_RD_BIT_ORDER); + } else { + // To do nothing + } + + // Disable flash operation mode + // As earlier as better, if not SPI_CTRL2 can not to be set delay cycles. + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_FLASH_MODE); + + // SPI mode type + if (SpiMode_Master == pAttr->mode) { + // SPI mode type + CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), SPI_SLAVE_MODE); + // SPI Send buffer + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO_HIGHPART );// By default slave send buffer C0-C7 + // SPI Speed + if (1 < (pAttr->speed)) { + CLEAR_PERI_REG_MASK(SPI_CLOCK(spiNum), SPI_CLK_EQU_SYSCLK); + WRITE_PERI_REG(SPI_CLOCK(spiNum), + ((pAttr->speed & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) | + ((((pAttr->speed + 1) / 2 - 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) | + ((pAttr->speed & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div + } else { + WRITE_PERI_REG(SPI_CLOCK(spiNum), SPI_CLK_EQU_SYSCLK); // 80Mhz speed + } + // By default format:CMD+ADDR+DATA + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_CS_SETUP | SPI_CS_HOLD | SPI_USR_MOSI ); + + //delay num + SET_PERI_REG_MASK(SPI_CTRL2(spiNum), ((0x1 & SPI_MISO_DELAY_NUM) << SPI_MISO_DELAY_NUM_S)); + } else if (SpiMode_Slave == pAttr->mode) { + // BIT19 must do + SET_PERI_REG_MASK(SPI_PIN(spiNum), BIT19); + + // SPI mode type + SET_PERI_REG_MASK(SPI_SLAVE(spiNum), SPI_SLAVE_MODE); + // SPI Send buffer + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO_HIGHPART);// By default slave send buffer C8-C15 + + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); + + // If do not set delay cycles, slave not working,master cann't get the data. + SET_PERI_REG_MASK(SPI_CTRL2(spiNum), ((0x1 & SPI_MOSI_DELAY_NUM) << SPI_MOSI_DELAY_NUM_S)); //delay num + // SPI Speed + WRITE_PERI_REG(SPI_CLOCK(spiNum), 0); + + // By default format::CMD(8bits)+ADDR(8bits)+DATA(32bytes). + SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN, + 7, SPI_USR_COMMAND_BITLEN_S); + SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_WR_ADDR_BITLEN, + 7, SPI_SLV_WR_ADDR_BITLEN_S); + SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_RD_ADDR_BITLEN, + 7, SPI_SLV_RD_ADDR_BITLEN_S); + SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_BUF_BITLEN, + (32 * 8 - 1), SPI_SLV_BUF_BITLEN_S); + // For 8266 work on slave mode. + SET_PERI_REG_BITS(SPI_SLAVE1(spiNum), SPI_SLV_STATUS_BITLEN, + 7, SPI_SLV_STATUS_BITLEN_S); + } else { + // To do nothing + } + + //clear Daul or Quad lines transmission mode + CLEAR_PERI_REG_MASK(SPI_CTRL(spiNum), SPI_QIO_MODE | SPI_DIO_MODE | SPI_DOUT_MODE | SPI_QOUT_MODE); +} + +/** + * @brief Set address value by master mode. + * + */ +void ICACHE_FLASH_ATTR SPIMasterCfgAddr(SpiNum spiNum, uint32_t addr) +{ + if (spiNum > SpiNum_HSPI) { + return; + } + // Set address + WRITE_PERI_REG(SPI_ADDR(spiNum), addr); +} + +/** + * @brief Set command value by master mode. + * + */ +void ICACHE_FLASH_ATTR SPIMasterCfgCmd(SpiNum spiNum, uint32_t cmd) +{ + if (spiNum > SpiNum_HSPI) { + return; + } + // SPI_USER2 bit28-31 is cmd length,cmd bit length is value(0-15)+1, + // bit15-0 is cmd value. + SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_VALUE, cmd, SPI_USR_COMMAND_VALUE_S); +} + +/** + * @brief Send data to slave. + * + */ +int ICACHE_FLASH_ATTR SPIMasterSendData(SpiNum spiNum, SpiData* pInData) +{ + char idx = 0; + if ((spiNum > SpiNum_HSPI) + || (NULL == pInData) + || (64 < pInData->dataLen)) { + return -1; + } + uint32_t *value = pInData->data; + while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); + // Set command by user. + if (pInData->cmdLen != 0) { + // Max command length 16 bits. + SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN, + ((pInData->cmdLen << 3) - 1), SPI_USR_COMMAND_BITLEN_S); + // Enable command + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND); + // Load command + SPIMasterCfgCmd(spiNum, pInData->cmd); + } else { + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND); + SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN, + 0, SPI_USR_COMMAND_BITLEN_S); + } + // Set Address by user. + if (pInData->addrLen == 0) { + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR); + SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN, + 0, SPI_USR_ADDR_BITLEN_S); + } else { + if (NULL == pInData->addr) { + return -1; + } + SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN, + ((pInData->addrLen << 3) - 1), SPI_USR_ADDR_BITLEN_S); + // Enable address + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR); + // Load address + SPIMasterCfgAddr(spiNum, *pInData->addr); + } + // Set data by user. + if (pInData->dataLen != 0) { + if (NULL == value) { + return -1; + } + // Enable MOSI + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO); + // Load send buffer + do { + WRITE_PERI_REG((SPI_W0(spiNum) + (idx << 2)), *value++); + } while (++idx < (pInData->dataLen / 4)); + // Set data send buffer length.Max data length 64 bytes. + SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN, ((pInData->dataLen << 3) - 1), SPI_USR_MOSI_BITLEN_S); + } else { + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); + SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN, + 0, SPI_USR_MOSI_BITLEN_S); + } + // Start send data + SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR); + + SHOWREG(); + return 0; +} + +/** + * @brief Receive data from slave. + * + */ +int ICACHE_FLASH_ATTR SPIMasterRecvData(SpiNum spiNum, SpiData* pOutData) +{ + char idx = 0; + if ((spiNum > SpiNum_HSPI) + || (NULL == pOutData)) { + return -1; + } + + uint32_t *value = pOutData->data; + while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); + // Set command by user. + if (pOutData->cmdLen != 0) { + // Max command length 16 bits. + SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN, + ((pOutData->cmdLen << 3) - 1), SPI_USR_COMMAND_BITLEN_S); + // Enable command + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND); + // Load command + SPIMasterCfgCmd(spiNum, pOutData->cmd); + } else { + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_COMMAND); + SET_PERI_REG_BITS(SPI_USER2(spiNum), SPI_USR_COMMAND_BITLEN, + 0, SPI_USR_COMMAND_BITLEN_S); + } + // Set Address by user. + if (pOutData->addrLen == 0) { + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR); + SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN, + 0, SPI_USR_ADDR_BITLEN_S); + } else { + if (NULL == pOutData->addr) { + return -1; + } + SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_ADDR_BITLEN, + ((pOutData->addrLen << 3) - 1), SPI_USR_ADDR_BITLEN_S); + // Enable address + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_ADDR); + // Load address + SPIMasterCfgAddr(spiNum, *pOutData->addr); + } + // Set data by user. + if (pOutData->dataLen != 0) { + if (NULL == value) { + return -1; + } + // Clear MOSI enable + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); + // Enable MOSI + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO); + // Set data send buffer length.Max data length 64 bytes. + SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN, ((pOutData->dataLen << 3) - 1), SPI_USR_MISO_BITLEN_S); + } else { + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO); + SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN, + 0, SPI_USR_MISO_BITLEN_S); + } + // Start send data + SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR); + + while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); + // Read data out + do { + *pOutData->data++ = READ_PERI_REG(SPI_W0(spiNum) + (idx << 2)); + } while (++idx < (pOutData->dataLen / 4)); + + SHOWREG(); + return 0; +} + +/** + * @brief Load data to send buffer by slave mode. + * + */ +int ICACHE_FLASH_ATTR SPISlaveSendData(SpiNum spiNum, uint32_t *pInData, uint8_t outLen) +{ + if (NULL == pInData) { + return -1; + } + char i; + for (i = 0; i < outLen; ++i) { + WRITE_PERI_REG((SPI_W8(spiNum) + (i << 2)), *pInData++); + } + return 0; +} + +/** + * @brief Configurate slave prepare for receive data. + * + */ +int ICACHE_FLASH_ATTR SPISlaveRecvData(SpiNum spiNum, void(*isrFunc)(void*)) +{ + if ((spiNum > SpiNum_HSPI)) { + return -1; + } + + SPIIntEnable(SpiNum_HSPI, SpiIntSrc_WrStaDoneEn + | SpiIntSrc_RdStaDoneEn | SpiIntSrc_WrBufDoneEn | SpiIntSrc_RdBufDoneEn); + SPIIntDisable(SpiNum_HSPI, SpiIntSrc_TransDoneEn); + + // Maybe enable slave transmission liston + SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR); + // + _xt_isr_attach(ETS_SPI_INUM, isrFunc, NULL); + // ETS_SPI_INTR_ATTACH(isrFunc, NULL); + // Enable isr + ETS_SPI_INTR_ENABLE(); + + + SHOWREG(); + + return 0; +} + +/** + * @brief Send data to slave(ESP8266 register of RD_STATUS or WR_STATUS). + * + */ +void ICACHE_FLASH_ATTR SPIMasterSendStatus(SpiNum spiNum, uint8_t data) +{ + if (spiNum > SpiNum_HSPI) { + return; + } + while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); + // Enable MOSI + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI); + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO | SPI_USR_DUMMY | SPI_USR_ADDR); + + // 8bits cmd, 0x04 is eps8266 slave write cmd value + WRITE_PERI_REG(SPI_USER2(spiNum), + ((7 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) + | MASTER_WRITE_STATUS_TO_SLAVE_CMD); + // Set data send buffer length. + SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MOSI_BITLEN, + ((sizeof(data) << 3) - 1), SPI_USR_MOSI_BITLEN_S); + + WRITE_PERI_REG(SPI_W0(spiNum), (uint32)(data)); + // Start SPI + SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR); + + SHOWREG(); +} + +/** + * @brief Receive status register from slave(ESP8266). + * + */ +int ICACHE_FLASH_ATTR SPIMasterRecvStatus(SpiNum spiNum) +{ + if (spiNum > SpiNum_HSPI) { + return -1; + } + + while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); + // Enable MISO + SET_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO); + CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MOSI | SPI_USR_DUMMY | SPI_USR_ADDR); + + // 8bits cmd, 0x06 is eps8266 slave read status cmd value + WRITE_PERI_REG(SPI_USER2(spiNum), + ((7 & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) + | MASTER_READ_STATUS_FROM_SLAVE_CMD); + // Set revcive buffer length. + SET_PERI_REG_BITS(SPI_USER1(spiNum), SPI_USR_MISO_BITLEN, + 7, SPI_USR_MISO_BITLEN_S); + + // start spi module. + SET_PERI_REG_MASK(SPI_CMD(spiNum), SPI_USR); + + while (READ_PERI_REG(SPI_CMD(spiNum))&SPI_USR); + + uint8_t data = (uint8)(READ_PERI_REG(SPI_W0(spiNum)) & 0xff); + SHOWREG(); + + return (uint8)(READ_PERI_REG(SPI_W0(spiNum)) & 0xff); +} + +/** + * @brief Select SPI CS pin. + * + */ +void ICACHE_FLASH_ATTR SPICsPinSelect(SpiNum spiNum, SpiPinCS pinCs) +{ + if (spiNum > SpiNum_HSPI) { + return; + } + // clear select + SET_PERI_REG_BITS(SPI_PIN(spiNum), 3, 0, 0); + SET_PERI_REG_MASK(SPI_PIN(spiNum), pinCs); +} + +/** + * @brief Enable SPI interrupt source. + * + */ +void ICACHE_FLASH_ATTR SPIIntEnable(SpiNum spiNum, SpiIntSrc intSrc) +{ + if (spiNum > SpiNum_HSPI) { + return; + } + SET_PERI_REG_MASK(SPI_SLAVE(spiNum), intSrc); +} + +/** + * @brief Disable SPI interrupt source. + * + */ +void ICACHE_FLASH_ATTR SPIIntDisable(SpiNum spiNum, SpiIntSrc intSrc) +{ + if (spiNum > SpiNum_HSPI) { + return; + } + CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), intSrc); +} + +/** + * @brief Clear all of SPI interrupt source. + * + */ +void ICACHE_FLASH_ATTR SPIIntClear(SpiNum spiNum) +{ + if (spiNum > SpiNum_HSPI) { + return; + } + CLEAR_PERI_REG_MASK(SPI_SLAVE(spiNum), SpiIntSrc_TransDoneEn + | SpiIntSrc_WrStaDoneEn + | SpiIntSrc_RdStaDoneEn + | SpiIntSrc_WrBufDoneEn + | SpiIntSrc_RdBufDoneEn); +} + + +#ifdef __cplusplus +} #endif \ No newline at end of file diff --git a/driver_lib/driver/uart.c b/driver_lib/driver/uart.c index 80314fa2..393845fc 100644 --- a/driver_lib/driver/uart.c +++ b/driver_lib/driver/uart.c @@ -1,435 +1,435 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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. - * - */ - -#include "esp_common.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" - -#include "uart.h" - -enum { - UART_EVENT_RX_CHAR, - UART_EVENT_MAX -}; - -typedef struct _os_event_ { - uint32 event; - uint32 param; -} os_event_t; - -xTaskHandle xUartTaskHandle; -xQueueHandle xQueueUart; - -LOCAL STATUS -uart_tx_one_char(uint8 uart, uint8 TxChar) -{ - while (true) { - uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); - - if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { - break; - } - } - - WRITE_PERI_REG(UART_FIFO(uart) , TxChar); - return OK; -} - -LOCAL void -uart1_write_char(char c) -{ - if (c == '\n') { - uart_tx_one_char(UART1, '\r'); - uart_tx_one_char(UART1, '\n'); - } else if (c == '\r') { - } else { - uart_tx_one_char(UART1, c); - } -} - -LOCAL void -uart0_write_char(char c) -{ - if (c == '\n') { - uart_tx_one_char(UART0, '\r'); - uart_tx_one_char(UART0, '\n'); - } else if (c == '\r') { - } else { - uart_tx_one_char(UART0, c); - } -} - -LOCAL void -uart_rx_intr_handler_ssc(void *arg) -{ - /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents - * uart1 and uart0 respectively - */ - os_event_t e; - portBASE_TYPE xHigherPriorityTaskWoken; - - uint8 RcvChar; - uint8 uart_no = 0; - - if (UART_RXFIFO_FULL_INT_ST != (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) { - return; - } - - RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF; - - WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR); - - e.event = UART_EVENT_RX_CHAR; - e.param = RcvChar; - - xQueueSendFromISR(xQueueUart, (void *)&e, &xHigherPriorityTaskWoken); - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); -} - -#if 0 -LOCAL void -uart_config(uint8 uart_no, UartDevice *uart) -{ - if (uart_no == UART1) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); - } else { - /* rcv_buff size if 0x100 */ - _xt_isr_attach(ETS_UART_INUM, uart_rx_intr_handler_ssc, NULL); - PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); - } - - uart_div_modify(uart_no, UART_CLK_FREQ / (uart->baut_rate)); - - WRITE_PERI_REG(UART_CONF0(uart_no), uart->exist_parity - | uart->parity - | (uart->stop_bits << UART_STOP_BIT_NUM_S) - | (uart->data_bits << UART_BIT_NUM_S)); - - //clear rx and tx fifo,not ready - SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); - CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); - - if (uart_no == UART0) { - //set rx fifo trigger - WRITE_PERI_REG(UART_CONF1(uart_no), - ((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); - } else { - WRITE_PERI_REG(UART_CONF1(uart_no), - ((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); - } - - //clear all interrupt - WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff); - //enable rx_interrupt - SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA); -} -#endif - -LOCAL void -uart_task(void *pvParameters) -{ - os_event_t e; - - for (;;) { - if (xQueueReceive(xQueueUart, (void *)&e, (portTickType)portMAX_DELAY)) { - switch (e.event) { - case UART_EVENT_RX_CHAR: - printf("%c", e.param); - break; - - default: - break; - } - } - } - - vTaskDelete(NULL); -} - -#if 0 -void -uart_init(void) -{ - while (READ_PERI_REG(UART_STATUS(0)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); - - while (READ_PERI_REG(UART_STATUS(1)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); - - UART_ConfigTypeDef uart; - - uart.baut_rate = BIT_RATE_74880; - uart.data_bits = UART_WordLength_8b; - uart.flow_ctrl = USART_HardwareFlowControl_None; - // uart.exist_parity = PARITY_DIS; - uart.parity = USART_Parity_None; - uart.stop_bits = USART_StopBits_1; - - uart_config(UART0, &uart); - uart_config(UART1, &uart); - - os_install_putc1(uart1_write_char); - - _xt_isr_unmask(1 << ETS_UART_INUM); - - xQueueUart = xQueueCreate(32, sizeof(os_event_t)); - - xTaskCreate(uart_task, (uint8 const *)"uTask", 512, NULL, tskIDLE_PRIORITY + 2, &xUartTaskHandle); -} -#endif - -//================================================================= - -void -UART_SetWordLength(UART_Port uart_no, UART_WordLength len) -{ - SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_BIT_NUM, len, UART_BIT_NUM_S); -} - -void -UART_SetStopBits(UART_Port uart_no, UART_StopBits bit_num) -{ - SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_STOP_BIT_NUM, bit_num, UART_STOP_BIT_NUM_S); -} - -void -UART_SetLineInverse(UART_Port uart_no, UART_LineLevelInverse inverse_mask) -{ - CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK); - SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask); -} - -void -UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) -{ - CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY | UART_PARITY_EN); - - if (Parity_mode == USART_Parity_None) { - } else { - SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode | UART_PARITY_EN); - } -} - -void -UART_SetBaudrate(UART_Port uart_no, uint32 baud_rate) -{ - uart_div_modify(uart_no, UART_CLK_FREQ / baud_rate); -} - -//only when USART_HardwareFlowControl_RTS is set , will the rx_thresh value be set. -void -UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh) -{ - if (flow_ctrl & USART_HardwareFlowControl_RTS) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); - SET_PERI_REG_BITS(UART_CONF1(uart_no), UART_RX_FLOW_THRHD, rx_thresh, UART_RX_FLOW_THRHD_S); - SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); - } else { - CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); - } - - if (flow_ctrl & USART_HardwareFlowControl_CTS) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS); - SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); - } else { - CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); - } -} - -void -UART_WaitTxFifoEmpty(UART_Port uart_no) //do not use if tx flow control enabled -{ - while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); -} - -void -UART_ResetFifo(UART_Port uart_no) -{ - SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); - CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); -} - -void -UART_ClearIntrStatus(UART_Port uart_no, uint32 clr_mask) -{ - WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask); -} - -void -UART_SetIntrEna(UART_Port uart_no, uint32 ena_mask) -{ - SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask); -} - -void -UART_intr_handler_register(void *fn, void *arg) -{ - _xt_isr_attach(ETS_UART_INUM, fn, arg); -} - -void -UART_SetPrintPort(UART_Port uart_no) -{ - if (uart_no == 1) { - os_install_putc1(uart1_write_char); - } else { - os_install_putc1(uart0_write_char); - } -} - -void -UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig) -{ - if (uart_no == UART1) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); - } else { - PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); - } - - UART_SetFlowCtrl(uart_no, pUARTConfig->flow_ctrl, pUARTConfig->UART_RxFlowThresh); - UART_SetBaudrate(uart_no, pUARTConfig->baud_rate); - - WRITE_PERI_REG(UART_CONF0(uart_no), - ((pUARTConfig->parity == USART_Parity_None) ? 0x0 : (UART_PARITY_EN | pUARTConfig->parity)) - | (pUARTConfig->stop_bits << UART_STOP_BIT_NUM_S) - | (pUARTConfig->data_bits << UART_BIT_NUM_S) - | ((pUARTConfig->flow_ctrl & USART_HardwareFlowControl_CTS) ? UART_TX_FLOW_EN : 0x0) - | pUARTConfig->UART_InverseMask); - - UART_ResetFifo(uart_no); -} - -void -UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf) -{ - - uint32 reg_val = 0; - UART_ClearIntrStatus(uart_no, UART_INTR_MASK); - reg_val = READ_PERI_REG(UART_CONF1(uart_no)) & ~((UART_RX_FLOW_THRHD << UART_RX_FLOW_THRHD_S) | UART_RX_FLOW_EN) ; - - reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_RXFIFO_TOUT_INT_ENA) ? - ((((pUARTIntrConf->UART_RX_TimeOutIntrThresh)&UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S) | UART_RX_TOUT_EN) : 0); - - reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_RXFIFO_FULL_INT_ENA) ? - (((pUARTIntrConf->UART_RX_FifoFullIntrThresh)&UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) : 0); - - reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_TXFIFO_EMPTY_INT_ENA) ? - (((pUARTIntrConf->UART_TX_FifoEmptyIntrThresh)&UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S) : 0); - - WRITE_PERI_REG(UART_CONF1(uart_no), reg_val); - CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_INTR_MASK); - SET_PERI_REG_MASK(UART_INT_ENA(uart_no), pUARTIntrConf->UART_IntrEnMask); -} - -LOCAL void -uart0_rx_intr_handler(void *para) -{ - /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents - * uart1 and uart0 respectively - */ - uint8 RcvChar; - uint8 uart_no = UART0;//UartDev.buff_uart_no; - uint8 fifo_len = 0; - uint8 buf_idx = 0; - uint8 fifo_tmp[128] = {0}; - - uint32 uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ; - - while (uart_intr_status != 0x0) { - if (UART_FRM_ERR_INT_ST == (uart_intr_status & UART_FRM_ERR_INT_ST)) { - //printf("FRM_ERR\r\n"); - WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR); - } else if (UART_RXFIFO_FULL_INT_ST == (uart_intr_status & UART_RXFIFO_FULL_INT_ST)) { - printf("full\r\n"); - fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; - buf_idx = 0; - - while (buf_idx < fifo_len) { - uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF); - buf_idx++; - } - - WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR); - } else if (UART_RXFIFO_TOUT_INT_ST == (uart_intr_status & UART_RXFIFO_TOUT_INT_ST)) { - printf("tout\r\n"); - fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; - buf_idx = 0; - - while (buf_idx < fifo_len) { - uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF); - buf_idx++; - } - - WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR); - } else if (UART_TXFIFO_EMPTY_INT_ST == (uart_intr_status & UART_TXFIFO_EMPTY_INT_ST)) { - printf("empty\n\r"); - WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR); - CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); - } else { - //skip - } - - uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ; - } -} - -void -uart_init_new(void) -{ - UART_WaitTxFifoEmpty(UART0); - UART_WaitTxFifoEmpty(UART1); - - UART_ConfigTypeDef uart_config; - uart_config.baud_rate = BIT_RATE_74880; - uart_config.data_bits = UART_WordLength_8b; - uart_config.parity = USART_Parity_None; - uart_config.stop_bits = USART_StopBits_1; - uart_config.flow_ctrl = USART_HardwareFlowControl_None; - uart_config.UART_RxFlowThresh = 120; - uart_config.UART_InverseMask = UART_None_Inverse; - UART_ParamConfig(UART0, &uart_config); - - UART_IntrConfTypeDef uart_intr; - uart_intr.UART_IntrEnMask = UART_RXFIFO_TOUT_INT_ENA | UART_FRM_ERR_INT_ENA | UART_RXFIFO_FULL_INT_ENA | UART_TXFIFO_EMPTY_INT_ENA; - uart_intr.UART_RX_FifoFullIntrThresh = 10; - uart_intr.UART_RX_TimeOutIntrThresh = 2; - uart_intr.UART_TX_FifoEmptyIntrThresh = 20; - UART_IntrConfig(UART0, &uart_intr); - - UART_SetPrintPort(UART0); - UART_intr_handler_register(uart0_rx_intr_handler, NULL); - ETS_UART_INTR_ENABLE(); - - /* - UART_SetWordLength(UART0,UART_WordLength_8b); - UART_SetStopBits(UART0,USART_StopBits_1); - UART_SetParity(UART0,USART_Parity_None); - UART_SetBaudrate(UART0,74880); - UART_SetFlowCtrl(UART0,USART_HardwareFlowControl_None,0); - */ - -} +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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. + * + */ + +#include "esp_common.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" + +#include "uart.h" + +enum { + UART_EVENT_RX_CHAR, + UART_EVENT_MAX +}; + +typedef struct _os_event_ { + uint32 event; + uint32 param; +} os_event_t; + +xTaskHandle xUartTaskHandle; +xQueueHandle xQueueUart; + +LOCAL STATUS +uart_tx_one_char(uint8 uart, uint8 TxChar) +{ + while (true) { + uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); + + if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { + break; + } + } + + WRITE_PERI_REG(UART_FIFO(uart) , TxChar); + return OK; +} + +LOCAL void +uart1_write_char(char c) +{ + if (c == '\n') { + uart_tx_one_char(UART1, '\r'); + uart_tx_one_char(UART1, '\n'); + } else if (c == '\r') { + } else { + uart_tx_one_char(UART1, c); + } +} + +LOCAL void +uart0_write_char(char c) +{ + if (c == '\n') { + uart_tx_one_char(UART0, '\r'); + uart_tx_one_char(UART0, '\n'); + } else if (c == '\r') { + } else { + uart_tx_one_char(UART0, c); + } +} + +LOCAL void +uart_rx_intr_handler_ssc(void *arg) +{ + /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents + * uart1 and uart0 respectively + */ + os_event_t e; + portBASE_TYPE xHigherPriorityTaskWoken; + + uint8 RcvChar; + uint8 uart_no = 0; + + if (UART_RXFIFO_FULL_INT_ST != (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) { + return; + } + + RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF; + + WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR); + + e.event = UART_EVENT_RX_CHAR; + e.param = RcvChar; + + xQueueSendFromISR(xQueueUart, (void *)&e, &xHigherPriorityTaskWoken); + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); +} + +#if 0 +LOCAL void +uart_config(uint8 uart_no, UartDevice *uart) +{ + if (uart_no == UART1) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); + } else { + /* rcv_buff size if 0x100 */ + _xt_isr_attach(ETS_UART_INUM, uart_rx_intr_handler_ssc, NULL); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); + } + + uart_div_modify(uart_no, UART_CLK_FREQ / (uart->baut_rate)); + + WRITE_PERI_REG(UART_CONF0(uart_no), uart->exist_parity + | uart->parity + | (uart->stop_bits << UART_STOP_BIT_NUM_S) + | (uart->data_bits << UART_BIT_NUM_S)); + + //clear rx and tx fifo,not ready + SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); + + if (uart_no == UART0) { + //set rx fifo trigger + WRITE_PERI_REG(UART_CONF1(uart_no), + ((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); + } else { + WRITE_PERI_REG(UART_CONF1(uart_no), + ((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); + } + + //clear all interrupt + WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff); + //enable rx_interrupt + SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA); +} +#endif + +LOCAL void +uart_task(void *pvParameters) +{ + os_event_t e; + + for (;;) { + if (xQueueReceive(xQueueUart, (void *)&e, (portTickType)portMAX_DELAY)) { + switch (e.event) { + case UART_EVENT_RX_CHAR: + printf("%c", e.param); + break; + + default: + break; + } + } + } + + vTaskDelete(NULL); +} + +#if 0 +void +uart_init(void) +{ + while (READ_PERI_REG(UART_STATUS(0)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); + + while (READ_PERI_REG(UART_STATUS(1)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); + + UART_ConfigTypeDef uart; + + uart.baut_rate = BIT_RATE_74880; + uart.data_bits = UART_WordLength_8b; + uart.flow_ctrl = USART_HardwareFlowControl_None; + // uart.exist_parity = PARITY_DIS; + uart.parity = USART_Parity_None; + uart.stop_bits = USART_StopBits_1; + + uart_config(UART0, &uart); + uart_config(UART1, &uart); + + os_install_putc1(uart1_write_char); + + _xt_isr_unmask(1 << ETS_UART_INUM); + + xQueueUart = xQueueCreate(32, sizeof(os_event_t)); + + xTaskCreate(uart_task, (uint8 const *)"uTask", 512, NULL, tskIDLE_PRIORITY + 2, &xUartTaskHandle); +} +#endif + +//================================================================= + +void +UART_SetWordLength(UART_Port uart_no, UART_WordLength len) +{ + SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_BIT_NUM, len, UART_BIT_NUM_S); +} + +void +UART_SetStopBits(UART_Port uart_no, UART_StopBits bit_num) +{ + SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_STOP_BIT_NUM, bit_num, UART_STOP_BIT_NUM_S); +} + +void +UART_SetLineInverse(UART_Port uart_no, UART_LineLevelInverse inverse_mask) +{ + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK); + SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask); +} + +void +UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) +{ + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY | UART_PARITY_EN); + + if (Parity_mode == USART_Parity_None) { + } else { + SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode | UART_PARITY_EN); + } +} + +void +UART_SetBaudrate(UART_Port uart_no, uint32 baud_rate) +{ + uart_div_modify(uart_no, UART_CLK_FREQ / baud_rate); +} + +//only when USART_HardwareFlowControl_RTS is set , will the rx_thresh value be set. +void +UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh) +{ + if (flow_ctrl & USART_HardwareFlowControl_RTS) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); + SET_PERI_REG_BITS(UART_CONF1(uart_no), UART_RX_FLOW_THRHD, rx_thresh, UART_RX_FLOW_THRHD_S); + SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); + } else { + CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); + } + + if (flow_ctrl & USART_HardwareFlowControl_CTS) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS); + SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); + } else { + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); + } +} + +void +UART_WaitTxFifoEmpty(UART_Port uart_no) //do not use if tx flow control enabled +{ + while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); +} + +void +UART_ResetFifo(UART_Port uart_no) +{ + SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); +} + +void +UART_ClearIntrStatus(UART_Port uart_no, uint32 clr_mask) +{ + WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask); +} + +void +UART_SetIntrEna(UART_Port uart_no, uint32 ena_mask) +{ + SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask); +} + +void +UART_intr_handler_register(void *fn, void *arg) +{ + _xt_isr_attach(ETS_UART_INUM, fn, arg); +} + +void +UART_SetPrintPort(UART_Port uart_no) +{ + if (uart_no == 1) { + os_install_putc1(uart1_write_char); + } else { + os_install_putc1(uart0_write_char); + } +} + +void +UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig) +{ + if (uart_no == UART1) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); + } else { + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); + } + + UART_SetFlowCtrl(uart_no, pUARTConfig->flow_ctrl, pUARTConfig->UART_RxFlowThresh); + UART_SetBaudrate(uart_no, pUARTConfig->baud_rate); + + WRITE_PERI_REG(UART_CONF0(uart_no), + ((pUARTConfig->parity == USART_Parity_None) ? 0x0 : (UART_PARITY_EN | pUARTConfig->parity)) + | (pUARTConfig->stop_bits << UART_STOP_BIT_NUM_S) + | (pUARTConfig->data_bits << UART_BIT_NUM_S) + | ((pUARTConfig->flow_ctrl & USART_HardwareFlowControl_CTS) ? UART_TX_FLOW_EN : 0x0) + | pUARTConfig->UART_InverseMask); + + UART_ResetFifo(uart_no); +} + +void +UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf) +{ + + uint32 reg_val = 0; + UART_ClearIntrStatus(uart_no, UART_INTR_MASK); + reg_val = READ_PERI_REG(UART_CONF1(uart_no)) & ~((UART_RX_FLOW_THRHD << UART_RX_FLOW_THRHD_S) | UART_RX_FLOW_EN) ; + + reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_RXFIFO_TOUT_INT_ENA) ? + ((((pUARTIntrConf->UART_RX_TimeOutIntrThresh)&UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S) | UART_RX_TOUT_EN) : 0); + + reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_RXFIFO_FULL_INT_ENA) ? + (((pUARTIntrConf->UART_RX_FifoFullIntrThresh)&UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) : 0); + + reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_TXFIFO_EMPTY_INT_ENA) ? + (((pUARTIntrConf->UART_TX_FifoEmptyIntrThresh)&UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S) : 0); + + WRITE_PERI_REG(UART_CONF1(uart_no), reg_val); + CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_INTR_MASK); + SET_PERI_REG_MASK(UART_INT_ENA(uart_no), pUARTIntrConf->UART_IntrEnMask); +} + +LOCAL void +uart0_rx_intr_handler(void *para) +{ + /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents + * uart1 and uart0 respectively + */ + uint8 RcvChar; + uint8 uart_no = UART0;//UartDev.buff_uart_no; + uint8 fifo_len = 0; + uint8 buf_idx = 0; + uint8 fifo_tmp[128] = {0}; + + uint32 uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ; + + while (uart_intr_status != 0x0) { + if (UART_FRM_ERR_INT_ST == (uart_intr_status & UART_FRM_ERR_INT_ST)) { + //printf("FRM_ERR\r\n"); + WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR); + } else if (UART_RXFIFO_FULL_INT_ST == (uart_intr_status & UART_RXFIFO_FULL_INT_ST)) { + printf("full\r\n"); + fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; + buf_idx = 0; + + while (buf_idx < fifo_len) { + uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF); + buf_idx++; + } + + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR); + } else if (UART_RXFIFO_TOUT_INT_ST == (uart_intr_status & UART_RXFIFO_TOUT_INT_ST)) { + printf("tout\r\n"); + fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; + buf_idx = 0; + + while (buf_idx < fifo_len) { + uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF); + buf_idx++; + } + + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR); + } else if (UART_TXFIFO_EMPTY_INT_ST == (uart_intr_status & UART_TXFIFO_EMPTY_INT_ST)) { + printf("empty\n\r"); + WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR); + CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); + } else { + //skip + } + + uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ; + } +} + +void +uart_init_new(void) +{ + UART_WaitTxFifoEmpty(UART0); + UART_WaitTxFifoEmpty(UART1); + + UART_ConfigTypeDef uart_config; + uart_config.baud_rate = BIT_RATE_74880; + uart_config.data_bits = UART_WordLength_8b; + uart_config.parity = USART_Parity_None; + uart_config.stop_bits = USART_StopBits_1; + uart_config.flow_ctrl = USART_HardwareFlowControl_None; + uart_config.UART_RxFlowThresh = 120; + uart_config.UART_InverseMask = UART_None_Inverse; + UART_ParamConfig(UART0, &uart_config); + + UART_IntrConfTypeDef uart_intr; + uart_intr.UART_IntrEnMask = UART_RXFIFO_TOUT_INT_ENA | UART_FRM_ERR_INT_ENA | UART_RXFIFO_FULL_INT_ENA | UART_TXFIFO_EMPTY_INT_ENA; + uart_intr.UART_RX_FifoFullIntrThresh = 10; + uart_intr.UART_RX_TimeOutIntrThresh = 2; + uart_intr.UART_TX_FifoEmptyIntrThresh = 20; + UART_IntrConfig(UART0, &uart_intr); + + UART_SetPrintPort(UART0); + UART_intr_handler_register(uart0_rx_intr_handler, NULL); + ETS_UART_INTR_ENABLE(); + + /* + UART_SetWordLength(UART0,UART_WordLength_8b); + UART_SetStopBits(UART0,USART_StopBits_1); + UART_SetParity(UART0,USART_Parity_None); + UART_SetBaudrate(UART0,74880); + UART_SetFlowCtrl(UART0,USART_HardwareFlowControl_None,0); + */ + +} diff --git a/driver_lib/include/gpio.h b/driver_lib/include/gpio.h index 1be6c536..4927a325 100644 --- a/driver_lib/include/gpio.h +++ b/driver_lib/include/gpio.h @@ -1,307 +1,307 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __GPIO_H__ -#define __GPIO_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define GPIO_Pin_0 (BIT(0)) /* Pin 0 selected */ -#define GPIO_Pin_1 (BIT(1)) /* Pin 1 selected */ -#define GPIO_Pin_2 (BIT(2)) /* Pin 2 selected */ -#define GPIO_Pin_3 (BIT(3)) /* Pin 3 selected */ -#define GPIO_Pin_4 (BIT(4)) /* Pin 4 selected */ -#define GPIO_Pin_5 (BIT(5)) /* Pin 5 selected */ -#define GPIO_Pin_6 (BIT(6)) /* Pin 6 selected */ -#define GPIO_Pin_7 (BIT(7)) /* Pin 7 selected */ -#define GPIO_Pin_8 (BIT(8)) /* Pin 8 selected */ -#define GPIO_Pin_9 (BIT(9)) /* Pin 9 selected */ -#define GPIO_Pin_10 (BIT(10)) /* Pin 10 selected */ -#define GPIO_Pin_11 (BIT(11)) /* Pin 11 selected */ -#define GPIO_Pin_12 (BIT(12)) /* Pin 12 selected */ -#define GPIO_Pin_13 (BIT(13)) /* Pin 13 selected */ -#define GPIO_Pin_14 (BIT(14)) /* Pin 14 selected */ -#define GPIO_Pin_15 (BIT(15)) /* Pin 15 selected */ -#define GPIO_Pin_All (0xFFFF) /* All pins selected */ - -#define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U -#define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U -#define GPIO_PIN_REG_2 PERIPHS_IO_MUX_GPIO2_U -#define GPIO_PIN_REG_3 PERIPHS_IO_MUX_U0RXD_U -#define GPIO_PIN_REG_4 PERIPHS_IO_MUX_GPIO4_U -#define GPIO_PIN_REG_5 PERIPHS_IO_MUX_GPIO5_U -#define GPIO_PIN_REG_6 PERIPHS_IO_MUX_SD_CLK_U -#define GPIO_PIN_REG_7 PERIPHS_IO_MUX_SD_DATA0_U -#define GPIO_PIN_REG_8 PERIPHS_IO_MUX_SD_DATA1_U -#define GPIO_PIN_REG_9 PERIPHS_IO_MUX_SD_DATA2_U -#define GPIO_PIN_REG_10 PERIPHS_IO_MUX_SD_DATA3_U -#define GPIO_PIN_REG_11 PERIPHS_IO_MUX_SD_CMD_U -#define GPIO_PIN_REG_12 PERIPHS_IO_MUX_MTDI_U -#define GPIO_PIN_REG_13 PERIPHS_IO_MUX_MTCK_U -#define GPIO_PIN_REG_14 PERIPHS_IO_MUX_MTMS_U -#define GPIO_PIN_REG_15 PERIPHS_IO_MUX_MTDO_U - -#define GPIO_PIN_REG(i) \ - (i==0) ? GPIO_PIN_REG_0: \ - (i==1) ? GPIO_PIN_REG_1: \ - (i==2) ? GPIO_PIN_REG_2: \ - (i==3) ? GPIO_PIN_REG_3: \ - (i==4) ? GPIO_PIN_REG_4: \ - (i==5) ? GPIO_PIN_REG_5: \ - (i==6) ? GPIO_PIN_REG_6: \ - (i==7) ? GPIO_PIN_REG_7: \ - (i==8) ? GPIO_PIN_REG_8: \ - (i==9) ? GPIO_PIN_REG_9: \ - (i==10)? GPIO_PIN_REG_10: \ - (i==11)? GPIO_PIN_REG_11: \ - (i==12)? GPIO_PIN_REG_12: \ - (i==13)? GPIO_PIN_REG_13: \ - (i==14)? GPIO_PIN_REG_14: \ - GPIO_PIN_REG_15 - -#define GPIO_PIN_ADDR(i) (GPIO_PIN0_ADDRESS + i*4) - -#define GPIO_ID_IS_PIN_REGISTER(reg_id) \ - ((reg_id >= GPIO_ID_PIN0) && (reg_id <= GPIO_ID_PIN(GPIO_PIN_COUNT-1))) - -#define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0) - -typedef enum { - GPIO_PIN_INTR_DISABLE = 0, /**< disable GPIO interrupt */ - GPIO_PIN_INTR_POSEDGE = 1, /**< GPIO interrupt type : rising edge */ - GPIO_PIN_INTR_NEGEDGE = 2, /**< GPIO interrupt type : falling edge */ - GPIO_PIN_INTR_ANYEDGE = 3, /**< GPIO interrupt type : bothe rising and falling edge */ - GPIO_PIN_INTR_LOLEVEL = 4, /**< GPIO interrupt type : low level */ - GPIO_PIN_INTR_HILEVEL = 5 /**< GPIO interrupt type : high level */ -} GPIO_INT_TYPE; - -typedef enum { - GPIO_Mode_Input = 0x0, /**< GPIO mode : Input */ - GPIO_Mode_Out_OD, /**< GPIO mode : Output_OD */ - GPIO_Mode_Output , /**< GPIO mode : Output */ - GPIO_Mode_Sigma_Delta , /**< GPIO mode : Sigma_Delta */ -} GPIOMode_TypeDef; - -typedef enum { - GPIO_PullUp_DIS = 0x0, /**< disable GPIO pullup */ - GPIO_PullUp_EN = 0x1, /**< enable GPIO pullup */ -} GPIO_Pullup_IF; - -typedef struct { - uint16 GPIO_Pin; /**< GPIO pin */ - GPIOMode_TypeDef GPIO_Mode; /**< GPIO mode */ - GPIO_Pullup_IF GPIO_Pullup; /**< GPIO pullup */ - GPIO_INT_TYPE GPIO_IntrType; /**< GPIO interrupt type */ -} GPIO_ConfigTypeDef; - -/** \defgroup Driver_APIs Driver APIs - * @brief Driver APIs - */ - -/** @addtogroup Driver_APIs - * @{ - */ - -/** \defgroup GPIO_Driver_APIs GPIO Driver APIs - * @brief GPIO APIs - */ - -/** @addtogroup GPIO_Driver_APIs - * @{ - */ - -/** - * @brief Set GPIO pin output level. - * - * @param gpio_no : The GPIO sequence number. - * @param bit_value : GPIO pin output level. - * - * @return null - */ -#define GPIO_OUTPUT_SET(gpio_no, bit_value) \ - gpio_output_conf(bit_value<>gpio_no)&BIT0) - -/** - * @brief Enable GPIO16 output. - * - * @param null - * - * @return null - */ -void gpio16_output_conf(void); - -/** - * @brief Set GPIO16 output level. - * - * @param uint8 value : GPIO16 output level. - * - * @return null - */ -void gpio16_output_set(uint8 value); - -/** - * @brief Enable GPIO pin intput. - * - * @param null - * - * @return null - */ -void gpio16_input_conf(void); - -/** - * @brief Sample the value of GPIO16 input. - * - * @param null - * - * @return the level of GPIO16 input. - */ -uint8 gpio16_input_get(void); - -/** - * @brief Configure Gpio pins out or input. - * - * @param uint32 set_mask : Set the output for the high bit, the - * corresponding bit is 1, the output of high, - * the corresponding bit is 0, do not change the state. - * @param uint32 set_mask : Set the output for the high bit, the - * corresponding bit is 1, the output of low, - * the corresponding bit is 0, do not change the state. - * @param uint32 enable_mask : Enable Output - * @param uint32 disable_mask : Enable Input - * - * @return null - */ -void gpio_output_conf(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask); - -/** - * @brief Register an application-specific interrupt handler for GPIO pin interrupts. - * - * @param void *fn:interrupt handler for GPIO pin interrupts. - * @param void *arg:interrupt handler's arg - * - * @return null - */ -void gpio_intr_handler_register(void *fn, void *arg); - -/** - * @brief Configure GPIO wake up to light sleep,Only level way is effective. - * - * @param uint32 i : Gpio sequence number - * @param GPIO_INT_TYPE intr_state : the level of wake up to light sleep - * - * @return null - */ -void gpio_pin_wakeup_enable(uint32 i, GPIO_INT_TYPE intr_state); - -/** - * @brief Disable GPIO wake up to light sleep. - * - * @param null - * - * @return null - */ -void gpio_pin_wakeup_disable(); - -/** - * @brief Config interrupt types of GPIO pin. - * - * @param uint32 i : The GPIO sequence number. - * @param GPIO_INT_TYPE intr_state : GPIO interrupt types. - * - * @return null - */ -void gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state); - -/** - * @brief Sample the value of GPIO input pins and returns a bitmask. - * - * @param null - * - * @return bitmask of GPIO pins input - */ -uint32 gpio_input_get(void); - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __GPIO_H__ +#define __GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define GPIO_Pin_0 (BIT(0)) /* Pin 0 selected */ +#define GPIO_Pin_1 (BIT(1)) /* Pin 1 selected */ +#define GPIO_Pin_2 (BIT(2)) /* Pin 2 selected */ +#define GPIO_Pin_3 (BIT(3)) /* Pin 3 selected */ +#define GPIO_Pin_4 (BIT(4)) /* Pin 4 selected */ +#define GPIO_Pin_5 (BIT(5)) /* Pin 5 selected */ +#define GPIO_Pin_6 (BIT(6)) /* Pin 6 selected */ +#define GPIO_Pin_7 (BIT(7)) /* Pin 7 selected */ +#define GPIO_Pin_8 (BIT(8)) /* Pin 8 selected */ +#define GPIO_Pin_9 (BIT(9)) /* Pin 9 selected */ +#define GPIO_Pin_10 (BIT(10)) /* Pin 10 selected */ +#define GPIO_Pin_11 (BIT(11)) /* Pin 11 selected */ +#define GPIO_Pin_12 (BIT(12)) /* Pin 12 selected */ +#define GPIO_Pin_13 (BIT(13)) /* Pin 13 selected */ +#define GPIO_Pin_14 (BIT(14)) /* Pin 14 selected */ +#define GPIO_Pin_15 (BIT(15)) /* Pin 15 selected */ +#define GPIO_Pin_All (0xFFFF) /* All pins selected */ + +#define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U +#define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U +#define GPIO_PIN_REG_2 PERIPHS_IO_MUX_GPIO2_U +#define GPIO_PIN_REG_3 PERIPHS_IO_MUX_U0RXD_U +#define GPIO_PIN_REG_4 PERIPHS_IO_MUX_GPIO4_U +#define GPIO_PIN_REG_5 PERIPHS_IO_MUX_GPIO5_U +#define GPIO_PIN_REG_6 PERIPHS_IO_MUX_SD_CLK_U +#define GPIO_PIN_REG_7 PERIPHS_IO_MUX_SD_DATA0_U +#define GPIO_PIN_REG_8 PERIPHS_IO_MUX_SD_DATA1_U +#define GPIO_PIN_REG_9 PERIPHS_IO_MUX_SD_DATA2_U +#define GPIO_PIN_REG_10 PERIPHS_IO_MUX_SD_DATA3_U +#define GPIO_PIN_REG_11 PERIPHS_IO_MUX_SD_CMD_U +#define GPIO_PIN_REG_12 PERIPHS_IO_MUX_MTDI_U +#define GPIO_PIN_REG_13 PERIPHS_IO_MUX_MTCK_U +#define GPIO_PIN_REG_14 PERIPHS_IO_MUX_MTMS_U +#define GPIO_PIN_REG_15 PERIPHS_IO_MUX_MTDO_U + +#define GPIO_PIN_REG(i) \ + (i==0) ? GPIO_PIN_REG_0: \ + (i==1) ? GPIO_PIN_REG_1: \ + (i==2) ? GPIO_PIN_REG_2: \ + (i==3) ? GPIO_PIN_REG_3: \ + (i==4) ? GPIO_PIN_REG_4: \ + (i==5) ? GPIO_PIN_REG_5: \ + (i==6) ? GPIO_PIN_REG_6: \ + (i==7) ? GPIO_PIN_REG_7: \ + (i==8) ? GPIO_PIN_REG_8: \ + (i==9) ? GPIO_PIN_REG_9: \ + (i==10)? GPIO_PIN_REG_10: \ + (i==11)? GPIO_PIN_REG_11: \ + (i==12)? GPIO_PIN_REG_12: \ + (i==13)? GPIO_PIN_REG_13: \ + (i==14)? GPIO_PIN_REG_14: \ + GPIO_PIN_REG_15 + +#define GPIO_PIN_ADDR(i) (GPIO_PIN0_ADDRESS + i*4) + +#define GPIO_ID_IS_PIN_REGISTER(reg_id) \ + ((reg_id >= GPIO_ID_PIN0) && (reg_id <= GPIO_ID_PIN(GPIO_PIN_COUNT-1))) + +#define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0) + +typedef enum { + GPIO_PIN_INTR_DISABLE = 0, /**< disable GPIO interrupt */ + GPIO_PIN_INTR_POSEDGE = 1, /**< GPIO interrupt type : rising edge */ + GPIO_PIN_INTR_NEGEDGE = 2, /**< GPIO interrupt type : falling edge */ + GPIO_PIN_INTR_ANYEDGE = 3, /**< GPIO interrupt type : bothe rising and falling edge */ + GPIO_PIN_INTR_LOLEVEL = 4, /**< GPIO interrupt type : low level */ + GPIO_PIN_INTR_HILEVEL = 5 /**< GPIO interrupt type : high level */ +} GPIO_INT_TYPE; + +typedef enum { + GPIO_Mode_Input = 0x0, /**< GPIO mode : Input */ + GPIO_Mode_Out_OD, /**< GPIO mode : Output_OD */ + GPIO_Mode_Output , /**< GPIO mode : Output */ + GPIO_Mode_Sigma_Delta , /**< GPIO mode : Sigma_Delta */ +} GPIOMode_TypeDef; + +typedef enum { + GPIO_PullUp_DIS = 0x0, /**< disable GPIO pullup */ + GPIO_PullUp_EN = 0x1, /**< enable GPIO pullup */ +} GPIO_Pullup_IF; + +typedef struct { + uint16 GPIO_Pin; /**< GPIO pin */ + GPIOMode_TypeDef GPIO_Mode; /**< GPIO mode */ + GPIO_Pullup_IF GPIO_Pullup; /**< GPIO pullup */ + GPIO_INT_TYPE GPIO_IntrType; /**< GPIO interrupt type */ +} GPIO_ConfigTypeDef; + +/** \defgroup Driver_APIs Driver APIs + * @brief Driver APIs + */ + +/** @addtogroup Driver_APIs + * @{ + */ + +/** \defgroup GPIO_Driver_APIs GPIO Driver APIs + * @brief GPIO APIs + */ + +/** @addtogroup GPIO_Driver_APIs + * @{ + */ + +/** + * @brief Set GPIO pin output level. + * + * @param gpio_no : The GPIO sequence number. + * @param bit_value : GPIO pin output level. + * + * @return null + */ +#define GPIO_OUTPUT_SET(gpio_no, bit_value) \ + gpio_output_conf(bit_value<>gpio_no)&BIT0) + +/** + * @brief Enable GPIO16 output. + * + * @param null + * + * @return null + */ +void gpio16_output_conf(void); + +/** + * @brief Set GPIO16 output level. + * + * @param uint8 value : GPIO16 output level. + * + * @return null + */ +void gpio16_output_set(uint8 value); + +/** + * @brief Enable GPIO pin intput. + * + * @param null + * + * @return null + */ +void gpio16_input_conf(void); + +/** + * @brief Sample the value of GPIO16 input. + * + * @param null + * + * @return the level of GPIO16 input. + */ +uint8 gpio16_input_get(void); + +/** + * @brief Configure Gpio pins out or input. + * + * @param uint32 set_mask : Set the output for the high bit, the + * corresponding bit is 1, the output of high, + * the corresponding bit is 0, do not change the state. + * @param uint32 set_mask : Set the output for the high bit, the + * corresponding bit is 1, the output of low, + * the corresponding bit is 0, do not change the state. + * @param uint32 enable_mask : Enable Output + * @param uint32 disable_mask : Enable Input + * + * @return null + */ +void gpio_output_conf(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask); + +/** + * @brief Register an application-specific interrupt handler for GPIO pin interrupts. + * + * @param void *fn:interrupt handler for GPIO pin interrupts. + * @param void *arg:interrupt handler's arg + * + * @return null + */ +void gpio_intr_handler_register(void *fn, void *arg); + +/** + * @brief Configure GPIO wake up to light sleep,Only level way is effective. + * + * @param uint32 i : Gpio sequence number + * @param GPIO_INT_TYPE intr_state : the level of wake up to light sleep + * + * @return null + */ +void gpio_pin_wakeup_enable(uint32 i, GPIO_INT_TYPE intr_state); + +/** + * @brief Disable GPIO wake up to light sleep. + * + * @param null + * + * @return null + */ +void gpio_pin_wakeup_disable(); + +/** + * @brief Config interrupt types of GPIO pin. + * + * @param uint32 i : The GPIO sequence number. + * @param GPIO_INT_TYPE intr_state : GPIO interrupt types. + * + * @return null + */ +void gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state); + +/** + * @brief Sample the value of GPIO input pins and returns a bitmask. + * + * @param null + * + * @return bitmask of GPIO pins input + */ +uint32 gpio_input_get(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/driver_lib/include/hw_timer.h b/driver_lib/include/hw_timer.h index e5f0564b..3cbb5407 100644 --- a/driver_lib/include/hw_timer.h +++ b/driver_lib/include/hw_timer.h @@ -1,85 +1,85 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __HW_TIMER_H__ -#define __HW_TIMER_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup HW_Timer_APIs Hardware timer APIs - * @brief Hardware timer APIs - * - * @attention Hardware timer can not interrupt other ISRs. - * - */ - -/** @addtogroup HW_Timer_APIs - * @{ - */ - - -/** - * @brief Initialize the hardware ISR timer. - * - * @param uint8 req : 0, not autoload; 1, autoload mode. - * - * @return null - */ -void hw_timer_init(uint8 req); - -/** - * @brief Set a trigger timer delay to enable this timer. - * - * @param uint32 val : Timing - * - In autoload mode, range : 50 ~ 0x7fffff - * - In non-autoload mode, range : 10 ~ 0x7fffff - * - * @return null - */ -void hw_timer_arm(uint32 val); - -/** - * @brief Set timer callback function. - * - * For enabled timer, timer callback has to be set. - * - * @param uint32 val : Timing - * - In autoload mode, range : 50 ~ 0x7fffff - * - In non-autoload mode, range : 10 ~ 0x7fffff - * - * @return null - */ -void hw_timer_set_func(void (* user_hw_timer_cb_set)(void)); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __HW_TIMER_H__ +#define __HW_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup HW_Timer_APIs Hardware timer APIs + * @brief Hardware timer APIs + * + * @attention Hardware timer can not interrupt other ISRs. + * + */ + +/** @addtogroup HW_Timer_APIs + * @{ + */ + + +/** + * @brief Initialize the hardware ISR timer. + * + * @param uint8 req : 0, not autoload; 1, autoload mode. + * + * @return null + */ +void hw_timer_init(uint8 req); + +/** + * @brief Set a trigger timer delay to enable this timer. + * + * @param uint32 val : Timing + * - In autoload mode, range : 50 ~ 0x7fffff + * - In non-autoload mode, range : 10 ~ 0x7fffff + * + * @return null + */ +void hw_timer_arm(uint32 val); + +/** + * @brief Set timer callback function. + * + * For enabled timer, timer callback has to be set. + * + * @param uint32 val : Timing + * - In autoload mode, range : 50 ~ 0x7fffff + * - In non-autoload mode, range : 10 ~ 0x7fffff + * + * @return null + */ +void hw_timer_set_func(void (* user_hw_timer_cb_set)(void)); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/driver_lib/include/i2c_master.h b/driver_lib/include/i2c_master.h old mode 100755 new mode 100644 index e83b4f11..1e7d645a --- a/driver_lib/include/i2c_master.h +++ b/driver_lib/include/i2c_master.h @@ -1,169 +1,169 @@ -#ifndef __I2C_MASTER_H__ -#define __I2C_MASTER_H__ - -#include "esp8266/pin_mux_register.h" -#define I2C_MASTER_SDA_MUX PERIPHS_IO_MUX_GPIO2_U -#define I2C_MASTER_SCL_MUX PERIPHS_IO_MUX_GPIO4_U -#define I2C_MASTER_SDA_GPIO 2 -#define I2C_MASTER_SCL_GPIO 4 -#define I2C_MASTER_SDA_FUNC FUNC_GPIO2 -#define I2C_MASTER_SCL_FUNC FUNC_GPIO4 - -//#define I2C_MASTER_SDA_MUX PERIPHS_IO_MUX_GPIO2_U -//#define I2C_MASTER_SCL_MUX PERIPHS_IO_MUX_GPIO0_U -//#define I2C_MASTER_SDA_GPIO 2 -//#define I2C_MASTER_SCL_GPIO 0 -//#define I2C_MASTER_SDA_FUNC FUNC_GPIO2 -//#define I2C_MASTER_SCL_FUNC FUNC_GPIO0 - -#if 0 -#define I2C_MASTER_GPIO_SET(pin) \ - gpio_output_set(1< - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __UART_H__ -#define __UART_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define ETS_UART_INTR_ENABLE() _xt_isr_unmask(1 << ETS_UART_INUM) -#define ETS_UART_INTR_DISABLE() _xt_isr_mask(1 << ETS_UART_INUM) -#define UART_INTR_MASK 0x1ff -#define UART_LINE_INV_MASK (0x3f<<19) - -typedef enum { - UART_WordLength_5b = 0x0, - UART_WordLength_6b = 0x1, - UART_WordLength_7b = 0x2, - UART_WordLength_8b = 0x3 -} UART_WordLength; - -typedef enum { - USART_StopBits_1 = 0x1, - USART_StopBits_1_5 = 0x2, - USART_StopBits_2 = 0x3, -} UART_StopBits; - -typedef enum { - UART0 = 0x0, - UART1 = 0x1, -} UART_Port; - -typedef enum { - USART_Parity_None = 0x2, - USART_Parity_Even = 0x0, - USART_Parity_Odd = 0x1 -} UART_ParityMode; - -typedef enum { - PARITY_DIS = 0x0, - PARITY_EN = 0x2 -} UartExistParity; - -typedef enum { - BIT_RATE_300 = 300, - BIT_RATE_600 = 600, - BIT_RATE_1200 = 1200, - BIT_RATE_2400 = 2400, - BIT_RATE_4800 = 4800, - BIT_RATE_9600 = 9600, - BIT_RATE_19200 = 19200, - BIT_RATE_38400 = 38400, - BIT_RATE_57600 = 57600, - BIT_RATE_74880 = 74880, - BIT_RATE_115200 = 115200, - BIT_RATE_230400 = 230400, - BIT_RATE_460800 = 460800, - BIT_RATE_921600 = 921600, - BIT_RATE_1843200 = 1843200, - BIT_RATE_3686400 = 3686400, -} UART_BautRate; //you can add any rate you need in this range - -typedef enum { - USART_HardwareFlowControl_None = 0x0, - USART_HardwareFlowControl_RTS = 0x1, - USART_HardwareFlowControl_CTS = 0x2, - USART_HardwareFlowControl_CTS_RTS = 0x3 -} UART_HwFlowCtrl; - -typedef enum { - UART_None_Inverse = 0x0, - UART_Rxd_Inverse = UART_RXD_INV, - UART_CTS_Inverse = UART_CTS_INV, - UART_Txd_Inverse = UART_TXD_INV, - UART_RTS_Inverse = UART_RTS_INV, -} UART_LineLevelInverse; - -typedef struct { - UART_BautRate baud_rate; - UART_WordLength data_bits; - UART_ParityMode parity; // chip size in byte - UART_StopBits stop_bits; - UART_HwFlowCtrl flow_ctrl; - uint8 UART_RxFlowThresh ; - uint32 UART_InverseMask; -} UART_ConfigTypeDef; - -typedef struct { - uint32 UART_IntrEnMask; - uint8 UART_RX_TimeOutIntrThresh; - uint8 UART_TX_FifoEmptyIntrThresh; - uint8 UART_RX_FifoFullIntrThresh; -} UART_IntrConfTypeDef; - -//======================================= - -/** \defgroup Driver_APIs Driver APIs - * @brief Driver APIs - */ - -/** @addtogroup Driver_APIs - * @{ - */ - -/** \defgroup UART_Driver_APIs UART Driver APIs - * @brief UART driver APIs - */ - -/** @addtogroup UART_Driver_APIs - * @{ - */ - -/** - * @brief Wait uart tx fifo empty, do not use it if tx flow control enabled. - * - * @param UART_Port uart_no:UART0 or UART1 - * - * @return null - */ -void UART_WaitTxFifoEmpty(UART_Port uart_no); //do not use if tx flow control enabled - -/** - * @brief Clear uart tx fifo and rx fifo. - * - * @param UART_Port uart_no : UART0 or UART1 - * - * @return null - */ -void UART_ResetFifo(UART_Port uart_no); - -/** - * @brief Clear uart interrupt flags. - * - * @param UART_Port uart_no : UART0 or UART1 - * @param uint32 clr_mask : To clear the interrupt bits - * - * @return null - */ -void UART_ClearIntrStatus(UART_Port uart_no, uint32 clr_mask); - -/** - * @brief Enable uart interrupts . - * - * @param UART_Port uart_no : UART0 or UART1 - * @param uint32 ena_mask : To enable the interrupt bits - * - * @return null - */ -void UART_SetIntrEna(UART_Port uart_no, uint32 ena_mask); - -/** - * @brief Register an application-specific interrupt handler for Uarts interrupts. - * - * @param void *fn : interrupt handler for Uart interrupts. - * @param void *arg : interrupt handler's arg. - * - * @return null - */ -void UART_intr_handler_register(void *fn, void *arg); - -/** - * @brief Config from which serial output printf function. - * - * @param UART_Port uart_no : UART0 or UART1 - * - * @return null - */ -void UART_SetPrintPort(UART_Port uart_no); - -/** - * @brief Config Common parameters of serial ports. - * - * @param UART_Port uart_no : UART0 or UART1 - * @param UART_ConfigTypeDef *pUARTConfig : parameters structure - * - * @return null - */ -void UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig); - -/** - * @brief Config types of uarts. - * - * @param UART_Port uart_no : UART0 or UART1 - * @param UART_IntrConfTypeDef *pUARTIntrConf : parameters structure - * - * @return null - */ -void UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf); - -/** - * @brief Config the length of the uart communication data bits. - * - * @param UART_Port uart_no : UART0 or UART1 - * @param UART_WordLength len : the length of the uart communication data bits - * - * @return null - */ -void UART_SetWordLength(UART_Port uart_no, UART_WordLength len); - -/** - * @brief Config the length of the uart communication stop bits. - * - * @param UART_Port uart_no : UART0 or UART1 - * @param UART_StopBits bit_num : the length uart communication stop bits - * - * @return null - */ -void UART_SetStopBits(UART_Port uart_no, UART_StopBits bit_num); - -/** - * @brief Configure whether to open the parity. - * - * @param UART_Port uart_no : UART0 or UART1 - * @param UART_ParityMode Parity_mode : the enum of uart parity configuration - * - * @return null - */ -void UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) ; - -/** - * @brief Configure the Baud rate. - * - * @param UART_Port uart_no : UART0 or UART1 - * @param uint32 baud_rate : the Baud rate - * - * @return null - */ -void UART_SetBaudrate(UART_Port uart_no, uint32 baud_rate); - -/** - * @brief Configure Hardware flow control. - * - * @param UART_Port uart_no : UART0 or UART1 - * @param UART_HwFlowCtrl flow_ctrl : Hardware flow control mode - * @param uint8 rx_thresh : threshold of Hardware flow control - * - * @return null - */ -void UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh); - -/** - * @brief Configure trigging signal of uarts. - * - * @param UART_Port uart_no : UART0 or UART1 - * @param UART_LineLevelInverse inverse_mask : Choose need to flip the IO - * - * @return null - */ -void UART_SetLineInverse(UART_Port uart_no, UART_LineLevelInverse inverse_mask) ; - -/** - * @brief An example illustrates how to configure the serial port. - * - * @param null - * - * @return null - */ -void uart_init_new(void); - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __UART_H__ +#define __UART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ETS_UART_INTR_ENABLE() _xt_isr_unmask(1 << ETS_UART_INUM) +#define ETS_UART_INTR_DISABLE() _xt_isr_mask(1 << ETS_UART_INUM) +#define UART_INTR_MASK 0x1ff +#define UART_LINE_INV_MASK (0x3f<<19) + +typedef enum { + UART_WordLength_5b = 0x0, + UART_WordLength_6b = 0x1, + UART_WordLength_7b = 0x2, + UART_WordLength_8b = 0x3 +} UART_WordLength; + +typedef enum { + USART_StopBits_1 = 0x1, + USART_StopBits_1_5 = 0x2, + USART_StopBits_2 = 0x3, +} UART_StopBits; + +typedef enum { + UART0 = 0x0, + UART1 = 0x1, +} UART_Port; + +typedef enum { + USART_Parity_None = 0x2, + USART_Parity_Even = 0x0, + USART_Parity_Odd = 0x1 +} UART_ParityMode; + +typedef enum { + PARITY_DIS = 0x0, + PARITY_EN = 0x2 +} UartExistParity; + +typedef enum { + BIT_RATE_300 = 300, + BIT_RATE_600 = 600, + BIT_RATE_1200 = 1200, + BIT_RATE_2400 = 2400, + BIT_RATE_4800 = 4800, + BIT_RATE_9600 = 9600, + BIT_RATE_19200 = 19200, + BIT_RATE_38400 = 38400, + BIT_RATE_57600 = 57600, + BIT_RATE_74880 = 74880, + BIT_RATE_115200 = 115200, + BIT_RATE_230400 = 230400, + BIT_RATE_460800 = 460800, + BIT_RATE_921600 = 921600, + BIT_RATE_1843200 = 1843200, + BIT_RATE_3686400 = 3686400, +} UART_BautRate; //you can add any rate you need in this range + +typedef enum { + USART_HardwareFlowControl_None = 0x0, + USART_HardwareFlowControl_RTS = 0x1, + USART_HardwareFlowControl_CTS = 0x2, + USART_HardwareFlowControl_CTS_RTS = 0x3 +} UART_HwFlowCtrl; + +typedef enum { + UART_None_Inverse = 0x0, + UART_Rxd_Inverse = UART_RXD_INV, + UART_CTS_Inverse = UART_CTS_INV, + UART_Txd_Inverse = UART_TXD_INV, + UART_RTS_Inverse = UART_RTS_INV, +} UART_LineLevelInverse; + +typedef struct { + UART_BautRate baud_rate; + UART_WordLength data_bits; + UART_ParityMode parity; // chip size in byte + UART_StopBits stop_bits; + UART_HwFlowCtrl flow_ctrl; + uint8 UART_RxFlowThresh ; + uint32 UART_InverseMask; +} UART_ConfigTypeDef; + +typedef struct { + uint32 UART_IntrEnMask; + uint8 UART_RX_TimeOutIntrThresh; + uint8 UART_TX_FifoEmptyIntrThresh; + uint8 UART_RX_FifoFullIntrThresh; +} UART_IntrConfTypeDef; + +//======================================= + +/** \defgroup Driver_APIs Driver APIs + * @brief Driver APIs + */ + +/** @addtogroup Driver_APIs + * @{ + */ + +/** \defgroup UART_Driver_APIs UART Driver APIs + * @brief UART driver APIs + */ + +/** @addtogroup UART_Driver_APIs + * @{ + */ + +/** + * @brief Wait uart tx fifo empty, do not use it if tx flow control enabled. + * + * @param UART_Port uart_no:UART0 or UART1 + * + * @return null + */ +void UART_WaitTxFifoEmpty(UART_Port uart_no); //do not use if tx flow control enabled + +/** + * @brief Clear uart tx fifo and rx fifo. + * + * @param UART_Port uart_no : UART0 or UART1 + * + * @return null + */ +void UART_ResetFifo(UART_Port uart_no); + +/** + * @brief Clear uart interrupt flags. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param uint32 clr_mask : To clear the interrupt bits + * + * @return null + */ +void UART_ClearIntrStatus(UART_Port uart_no, uint32 clr_mask); + +/** + * @brief Enable uart interrupts . + * + * @param UART_Port uart_no : UART0 or UART1 + * @param uint32 ena_mask : To enable the interrupt bits + * + * @return null + */ +void UART_SetIntrEna(UART_Port uart_no, uint32 ena_mask); + +/** + * @brief Register an application-specific interrupt handler for Uarts interrupts. + * + * @param void *fn : interrupt handler for Uart interrupts. + * @param void *arg : interrupt handler's arg. + * + * @return null + */ +void UART_intr_handler_register(void *fn, void *arg); + +/** + * @brief Config from which serial output printf function. + * + * @param UART_Port uart_no : UART0 or UART1 + * + * @return null + */ +void UART_SetPrintPort(UART_Port uart_no); + +/** + * @brief Config Common parameters of serial ports. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_ConfigTypeDef *pUARTConfig : parameters structure + * + * @return null + */ +void UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig); + +/** + * @brief Config types of uarts. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_IntrConfTypeDef *pUARTIntrConf : parameters structure + * + * @return null + */ +void UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf); + +/** + * @brief Config the length of the uart communication data bits. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_WordLength len : the length of the uart communication data bits + * + * @return null + */ +void UART_SetWordLength(UART_Port uart_no, UART_WordLength len); + +/** + * @brief Config the length of the uart communication stop bits. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_StopBits bit_num : the length uart communication stop bits + * + * @return null + */ +void UART_SetStopBits(UART_Port uart_no, UART_StopBits bit_num); + +/** + * @brief Configure whether to open the parity. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_ParityMode Parity_mode : the enum of uart parity configuration + * + * @return null + */ +void UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) ; + +/** + * @brief Configure the Baud rate. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param uint32 baud_rate : the Baud rate + * + * @return null + */ +void UART_SetBaudrate(UART_Port uart_no, uint32 baud_rate); + +/** + * @brief Configure Hardware flow control. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_HwFlowCtrl flow_ctrl : Hardware flow control mode + * @param uint8 rx_thresh : threshold of Hardware flow control + * + * @return null + */ +void UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh); + +/** + * @brief Configure trigging signal of uarts. + * + * @param UART_Port uart_no : UART0 or UART1 + * @param UART_LineLevelInverse inverse_mask : Choose need to flip the IO + * + * @return null + */ +void UART_SetLineInverse(UART_Port uart_no, UART_LineLevelInverse inverse_mask) ; + +/** + * @brief An example illustrates how to configure the serial port. + * + * @param null + * + * @return null + */ +void uart_init_new(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/openssl_demo/Makefile b/examples/openssl_demo/Makefile index 8f76385b..f4657685 100644 --- a/examples/openssl_demo/Makefile +++ b/examples/openssl_demo/Makefile @@ -1,123 +1,123 @@ -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of object file images to be generated () -# GEN_BINS - list of binaries to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -TARGET = eagle -#FLAVOR = release -FLAVOR = debug - -#EXTRA_CCFLAGS += -u - -ifndef PDIR # { -GEN_IMAGES= eagle.app.v6.out -GEN_BINS= eagle.app.v6.bin -SPECIAL_MKTARGETS=$(APP_MKTARGETS) -SUBDIRS= \ - user \ - programs - -endif # } PDIR - -LDDIR = $(SDK_PATH)/ld - -CCFLAGS += -Os - -TARGET_LDFLAGS = \ - -nostdlib \ - -Wl,-EL \ - --longcalls \ - --text-section-literals - -ifeq ($(FLAVOR),debug) - TARGET_LDFLAGS += -g -O2 -endif - -ifeq ($(FLAVOR),release) - TARGET_LDFLAGS += -g -O0 -endif - -COMPONENTS_eagle.app.v6 = \ - user/libuser.a \ - programs/openssl_demo.a - -LINKFLAGS_eagle.app.v6 = \ - -L$(SDK_PATH)/lib \ - -Wl,--gc-sections \ - -nostdlib \ - -T$(LD_FILE) \ - -Wl,--no-check-sections \ - -u call_user_start \ - -Wl,-static \ - -Wl,--start-group \ - -lcirom \ - -lgcc \ - -lhal \ - -lcrypto \ - -lfreertos \ - -llwip \ - -lmain \ - -lnet80211 \ - -lphy \ - -lpp \ - -lmbedtls \ - -lopenssl \ - -lwpa \ - $(DEP_LIBS_eagle.app.v6)\ - -Wl,--end-group - -DEPENDS_eagle.app.v6 = \ - $(LD_FILE) \ - $(LDDIR)/eagle.rom.addr.v6.ld - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# - -#UNIVERSAL_TARGET_DEFINES = \ - -# Other potential configuration flags include: -# -DTXRX_TXBUF_DEBUG -# -DTXRX_RXBUF_DEBUG -# -DWLAN_CONFIG_CCX -CONFIGURATION_DEFINES = -DICACHE_FLASH - -DEFINES += \ - $(UNIVERSAL_TARGET_DEFINES) \ - $(CONFIGURATION_DEFINES) - -DDEFINES += \ - $(UNIVERSAL_TARGET_DEFINES) \ - $(CONFIGURATION_DEFINES) - - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -I include -I $(SDK_PATH)/include/openssl -sinclude $(SDK_PATH)/Makefile - -.PHONY: FORCE -FORCE: - +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of object file images to be generated () +# GEN_BINS - list of binaries to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +TARGET = eagle +#FLAVOR = release +FLAVOR = debug + +#EXTRA_CCFLAGS += -u + +ifndef PDIR # { +GEN_IMAGES= eagle.app.v6.out +GEN_BINS= eagle.app.v6.bin +SPECIAL_MKTARGETS=$(APP_MKTARGETS) +SUBDIRS= \ + user \ + programs + +endif # } PDIR + +LDDIR = $(SDK_PATH)/ld + +CCFLAGS += -Os + +TARGET_LDFLAGS = \ + -nostdlib \ + -Wl,-EL \ + --longcalls \ + --text-section-literals + +ifeq ($(FLAVOR),debug) + TARGET_LDFLAGS += -g -O2 +endif + +ifeq ($(FLAVOR),release) + TARGET_LDFLAGS += -g -O0 +endif + +COMPONENTS_eagle.app.v6 = \ + user/libuser.a \ + programs/openssl_demo.a + +LINKFLAGS_eagle.app.v6 = \ + -L$(SDK_PATH)/lib \ + -Wl,--gc-sections \ + -nostdlib \ + -T$(LD_FILE) \ + -Wl,--no-check-sections \ + -u call_user_start \ + -Wl,-static \ + -Wl,--start-group \ + -lcirom \ + -lgcc \ + -lhal \ + -lcrypto \ + -lfreertos \ + -llwip \ + -lmain \ + -lnet80211 \ + -lphy \ + -lpp \ + -lmbedtls \ + -lopenssl \ + -lwpa \ + $(DEP_LIBS_eagle.app.v6)\ + -Wl,--end-group + +DEPENDS_eagle.app.v6 = \ + $(LD_FILE) \ + $(LDDIR)/eagle.rom.addr.v6.ld + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# + +#UNIVERSAL_TARGET_DEFINES = \ + +# Other potential configuration flags include: +# -DTXRX_TXBUF_DEBUG +# -DTXRX_RXBUF_DEBUG +# -DWLAN_CONFIG_CCX +CONFIGURATION_DEFINES = -DICACHE_FLASH + +DEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + +DDEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include -I include -I $(SDK_PATH)/include/openssl +sinclude $(SDK_PATH)/Makefile + +.PHONY: FORCE +FORCE: + diff --git a/examples/openssl_demo/include/user_config.h b/examples/openssl_demo/include/user_config.h index dc4e128c..9191e5a4 100644 --- a/examples/openssl_demo/include/user_config.h +++ b/examples/openssl_demo/include/user_config.h @@ -1,34 +1,34 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __USER_CONFIG_H__ -#define __USER_CONFIG_H__ - -#include "openssl_demo.h" - -#define SSID "UTT-750" -#define PASSWORD "espressif" - -#endif - +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __USER_CONFIG_H__ +#define __USER_CONFIG_H__ + +#include "openssl_demo.h" + +#define SSID "UTT-750" +#define PASSWORD "espressif" + +#endif + diff --git a/examples/openssl_demo/programs/Makefile b/examples/openssl_demo/programs/Makefile index 5c74dba6..07ea9b96 100644 --- a/examples/openssl_demo/programs/Makefile +++ b/examples/openssl_demo/programs/Makefile @@ -1,47 +1,47 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -UP_EXTRACT_DIR = .. -GEN_LIBS = openssl_demo.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +UP_EXTRACT_DIR = .. +GEN_LIBS = openssl_demo.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/examples/openssl_demo/user/Makefile b/examples/openssl_demo/user/Makefile index d57d85da..dd3837c7 100644 --- a/examples/openssl_demo/user/Makefile +++ b/examples/openssl_demo/user/Makefile @@ -1,44 +1,44 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR -GEN_LIBS = libuser.a -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +GEN_LIBS = libuser.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/examples/openssl_demo/user/user_main.c b/examples/openssl_demo/user/user_main.c index 02727d2f..49b1d734 100644 --- a/examples/openssl_demo/user/user_main.c +++ b/examples/openssl_demo/user/user_main.c @@ -1,108 +1,108 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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. - * - */ - -#include "esp_common.h" -#include "user_config.h" - -/****************************************************************************** - * FunctionName : user_rf_cal_sector_set - * Description : SDK just reversed 4 sectors, used for rf init data and paramters. - * We add this function to force users to set rf cal sector, since - * we don't know which sector is free in user's application. - * sector map for last several sectors : ABCCC - * A : rf cal - * B : rf init data - * C : sdk parameters - * Parameters : none - * Returns : rf cal sector -*******************************************************************************/ -uint32 user_rf_cal_sector_set(void) -{ - flash_size_map size_map = system_get_flash_size_map(); - uint32 rf_cal_sec = 0; - - switch (size_map) { - case FLASH_SIZE_4M_MAP_256_256: - rf_cal_sec = 128 - 5; - break; - - case FLASH_SIZE_8M_MAP_512_512: - rf_cal_sec = 256 - 5; - break; - - case FLASH_SIZE_16M_MAP_512_512: - case FLASH_SIZE_16M_MAP_1024_1024: - rf_cal_sec = 512 - 5; - break; - - case FLASH_SIZE_32M_MAP_512_512: - case FLASH_SIZE_32M_MAP_1024_1024: - rf_cal_sec = 1024 - 5; - break; - - default: - rf_cal_sec = 0; - break; - } - - return rf_cal_sec; -} - -void wifi_event_handler_cb(System_Event_t *event) -{ - if (event == NULL) { - return; - } - - switch (event->event_id) { - case EVENT_STAMODE_GOT_IP: - os_printf("sta got ip , creat task %d\n", system_get_free_heap_size()); - user_conn_init(); - break; - - default: - break; - } -} - -/****************************************************************************** - * FunctionName : user_init - * Description : entry of user application, init user function here - * Parameters : none - * Returns : none -*******************************************************************************/ -void user_init(void) -{ - os_printf("SDK version:%s %d\n", system_get_sdk_version(), system_get_free_heap_size()); - wifi_set_opmode(STATION_MODE); - - // set AP parameter - struct station_config config; - bzero(&config, sizeof(struct station_config)); - sprintf(config.ssid, SSID); - sprintf(config.password, PASSWORD); - wifi_station_set_config(&config); - - wifi_set_event_handler_cb(wifi_event_handler_cb); -} +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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. + * + */ + +#include "esp_common.h" +#include "user_config.h" + +/****************************************************************************** + * FunctionName : user_rf_cal_sector_set + * Description : SDK just reversed 4 sectors, used for rf init data and paramters. + * We add this function to force users to set rf cal sector, since + * we don't know which sector is free in user's application. + * sector map for last several sectors : ABCCC + * A : rf cal + * B : rf init data + * C : sdk parameters + * Parameters : none + * Returns : rf cal sector +*******************************************************************************/ +uint32 user_rf_cal_sector_set(void) +{ + flash_size_map size_map = system_get_flash_size_map(); + uint32 rf_cal_sec = 0; + + switch (size_map) { + case FLASH_SIZE_4M_MAP_256_256: + rf_cal_sec = 128 - 5; + break; + + case FLASH_SIZE_8M_MAP_512_512: + rf_cal_sec = 256 - 5; + break; + + case FLASH_SIZE_16M_MAP_512_512: + case FLASH_SIZE_16M_MAP_1024_1024: + rf_cal_sec = 512 - 5; + break; + + case FLASH_SIZE_32M_MAP_512_512: + case FLASH_SIZE_32M_MAP_1024_1024: + rf_cal_sec = 1024 - 5; + break; + + default: + rf_cal_sec = 0; + break; + } + + return rf_cal_sec; +} + +void wifi_event_handler_cb(System_Event_t *event) +{ + if (event == NULL) { + return; + } + + switch (event->event_id) { + case EVENT_STAMODE_GOT_IP: + os_printf("sta got ip , creat task %d\n", system_get_free_heap_size()); + user_conn_init(); + break; + + default: + break; + } +} + +/****************************************************************************** + * FunctionName : user_init + * Description : entry of user application, init user function here + * Parameters : none + * Returns : none +*******************************************************************************/ +void user_init(void) +{ + os_printf("SDK version:%s %d\n", system_get_sdk_version(), system_get_free_heap_size()); + wifi_set_opmode(STATION_MODE); + + // set AP parameter + struct station_config config; + bzero(&config, sizeof(struct station_config)); + sprintf(config.ssid, SSID); + sprintf(config.password, PASSWORD); + wifi_station_set_config(&config); + + wifi_set_event_handler_cb(wifi_event_handler_cb); +} diff --git a/examples/project_template/Makefile b/examples/project_template/Makefile index b8dd20fd..9baf6760 100644 --- a/examples/project_template/Makefile +++ b/examples/project_template/Makefile @@ -1,132 +1,132 @@ -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of object file images to be generated () -# GEN_BINS - list of binaries to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -TARGET = eagle -#FLAVOR = release -FLAVOR = debug - -#EXTRA_CCFLAGS += -u - -ifndef PDIR # { -GEN_IMAGES= eagle.app.v6.out -GEN_BINS= eagle.app.v6.bin -SPECIAL_MKTARGETS=$(APP_MKTARGETS) -SUBDIRS= \ - user \ - sample_lib - -endif # } PDIR - -LDDIR = $(SDK_PATH)/ld - -CCFLAGS += -Os - -TARGET_LDFLAGS = \ - -nostdlib \ - -Wl,-EL \ - --longcalls \ - --text-section-literals - -ifeq ($(FLAVOR),debug) - TARGET_LDFLAGS += -g -O2 -endif - -ifeq ($(FLAVOR),release) - TARGET_LDFLAGS += -g -O0 -endif - -COMPONENTS_eagle.app.v6 = \ - user/libuser.a \ - sample_lib/libsample.a - -LINKFLAGS_eagle.app.v6 = \ - -L$(SDK_PATH)/lib \ - -Wl,--gc-sections \ - -nostdlib \ - -T$(LD_FILE) \ - -Wl,--no-check-sections \ - -u call_user_start \ - -Wl,-static \ - -Wl,--start-group \ - -lcirom \ - -lcrypto \ - -lespconn \ - -lespnow \ - -lfreertos \ - -lgcc \ - -lhal \ - -ljson \ - -llwip \ - -lmain \ - -lmesh \ - -lmirom \ - -lnet80211 \ - -lnopoll \ - -lphy \ - -lpp \ - -lpwm \ - -lsmartconfig \ - -lspiffs \ - -lssl \ - -lwpa \ - -lwps \ - $(DEP_LIBS_eagle.app.v6) \ - -Wl,--end-group - -DEPENDS_eagle.app.v6 = \ - $(LD_FILE) \ - $(LDDIR)/eagle.rom.addr.v6.ld - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# - -#UNIVERSAL_TARGET_DEFINES = \ - -# Other potential configuration flags include: -# -DTXRX_TXBUF_DEBUG -# -DTXRX_RXBUF_DEBUG -# -DWLAN_CONFIG_CCX -CONFIGURATION_DEFINES = -DICACHE_FLASH - -DEFINES += \ - $(UNIVERSAL_TARGET_DEFINES) \ - $(CONFIGURATION_DEFINES) - -DDEFINES += \ - $(UNIVERSAL_TARGET_DEFINES) \ - $(CONFIGURATION_DEFINES) - - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -sinclude $(SDK_PATH)/Makefile - -.PHONY: FORCE -FORCE: - +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of object file images to be generated () +# GEN_BINS - list of binaries to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +TARGET = eagle +#FLAVOR = release +FLAVOR = debug + +#EXTRA_CCFLAGS += -u + +ifndef PDIR # { +GEN_IMAGES= eagle.app.v6.out +GEN_BINS= eagle.app.v6.bin +SPECIAL_MKTARGETS=$(APP_MKTARGETS) +SUBDIRS= \ + user \ + sample_lib + +endif # } PDIR + +LDDIR = $(SDK_PATH)/ld + +CCFLAGS += -Os + +TARGET_LDFLAGS = \ + -nostdlib \ + -Wl,-EL \ + --longcalls \ + --text-section-literals + +ifeq ($(FLAVOR),debug) + TARGET_LDFLAGS += -g -O2 +endif + +ifeq ($(FLAVOR),release) + TARGET_LDFLAGS += -g -O0 +endif + +COMPONENTS_eagle.app.v6 = \ + user/libuser.a \ + sample_lib/libsample.a + +LINKFLAGS_eagle.app.v6 = \ + -L$(SDK_PATH)/lib \ + -Wl,--gc-sections \ + -nostdlib \ + -T$(LD_FILE) \ + -Wl,--no-check-sections \ + -u call_user_start \ + -Wl,-static \ + -Wl,--start-group \ + -lcirom \ + -lcrypto \ + -lespconn \ + -lespnow \ + -lfreertos \ + -lgcc \ + -lhal \ + -ljson \ + -llwip \ + -lmain \ + -lmesh \ + -lmirom \ + -lnet80211 \ + -lnopoll \ + -lphy \ + -lpp \ + -lpwm \ + -lsmartconfig \ + -lspiffs \ + -lssl \ + -lwpa \ + -lwps \ + $(DEP_LIBS_eagle.app.v6) \ + -Wl,--end-group + +DEPENDS_eagle.app.v6 = \ + $(LD_FILE) \ + $(LDDIR)/eagle.rom.addr.v6.ld + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# + +#UNIVERSAL_TARGET_DEFINES = \ + +# Other potential configuration flags include: +# -DTXRX_TXBUF_DEBUG +# -DTXRX_RXBUF_DEBUG +# -DWLAN_CONFIG_CCX +CONFIGURATION_DEFINES = -DICACHE_FLASH + +DEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + +DDEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +sinclude $(SDK_PATH)/Makefile + +.PHONY: FORCE +FORCE: + diff --git a/examples/project_template/gen_misc.bat b/examples/project_template/gen_misc.bat index fd0b44fe..fbb53be7 100644 --- a/examples/project_template/gen_misc.bat +++ b/examples/project_template/gen_misc.bat @@ -1,172 +1,172 @@ -@echo off - -Rem ******NOTICE****** -Rem MUST set SDK_PATH & BIN_PATH firstly!!! -Rem example: -Rem set SDK_PATH=/c/esp_iot_sdk_freertos -Rem set BIN_PATH=/c/esp8266_bin - -set SDK_PATH="" -set BIN_PATH="" - -echo gen_misc.bat version 20150911 -echo . - -if not %SDK_PATH% == "" ( - echo SDK_PATH: %SDK_PATH% -) else ( - echo ERROR: Please set SDK_PATH in gen_misc.bat firstly, exit!!! - goto end -) - -if not %BIN_PATH% == "" ( - echo BIN_PATH: %BIN_PATH% -) else ( - echo ERROR: Please set BIN_PATH in gen_misc.bat firstly, exit!!! - goto end -) - -echo . -echo Please check SDK_PATH/BIN_PATH, enter (Y/y) to continue: -set input=default -set /p input= - -if not %input% == Y ( - if not %input% == y ( - goto end - ) -) - -echo . -echo Please follow below steps(1-5) to generate specific bin(s): -echo STEP 1: use boot_v1.2+ by default -set boot=new - -echo boot mode: %boot% -echo. - -echo STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin) -set input=default -set /p input=enter (0/1/2, default 0): - -if %input% equ 1 ( - if %boot% equ none ( - set app=0 - echo choose no boot before - echo generate bin: eagle.flash.bin+eagle.irom0text.bin - ) else ( - set app=1 - echo generate bin: user1.bin - ) -) else ( -if %input% equ 2 ( - if %boot% equ none ( - set app=0 - echo choose no boot before - echo generate bin: eagle.flash.bin+eagle.irom0text.bin - ) else ( - set app=2 - echo generate bin: user2.bin - ) -) else ( - if %boot% neq none ( - set boot=none - echo ignore boot - ) - set app=0 - echo generate bin: eagle.flash.bin+eagle.irom0text.bin -)) - -echo. - -echo STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz) -set input=default -set /p input=enter (0/1/2/3, default 2): - -if %input% equ 0 ( - set spi_speed=20 -) else ( -if %input% equ 1 ( - set spi_speed=26.7 -) else ( -if %input% equ 3 ( - set spi_speed=80 -) else ( - set spi_speed=40 -))) - -echo spi speed: %spi_speed% MHz -echo. - -echo STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT) -set input=default -set /p input=enter (0/1/2/3, default 0): - -if %input% equ 1 ( - set spi_mode=QOUT -) else ( -if %input% equ 2 ( - set spi_mode=DIO -) else ( -if %input% equ 3 ( - set spi_mode=DOUT -) else ( - set spi_mode=QIO -))) - -echo spi mode: %spi_mode% -echo. - -echo STEP 5: choose flash size and map -echo 0= 512KB( 256KB+ 256KB) -echo 2=1024KB( 512KB+ 512KB) -echo 3=2048KB( 512KB+ 512KB) -echo 4=4096KB( 512KB+ 512KB) -echo 5=2048KB(1024KB+1024KB) -echo 6=4096KB(1024KB+1024KB) -set input=default -set /p input=enter (0/1/2/3/4/5/6, default 0): - -if %input% equ 2 ( - set spi_size_map=2 - echo spi size: 1024KB - echo spi ota map: 512KB + 512KB -) else ( - if %input% equ 3 ( - set spi_size_map=3 - echo spi size: 2048KB - echo spi ota map: 512KB + 512KB - ) else ( - if %input% equ 4 ( - set spi_size_map=4 - echo spi size: 4096KB - echo spi ota map: 512KB + 512KB - ) else ( - if %input% equ 5 ( - set spi_size_map=5 - echo spi size: 2048KB - echo spi ota map: 1024KB + 1024KB - ) else ( - if %input% equ 6 ( - set spi_size_map=6 - echo spi size: 4096KB - echo spi ota map: 1024KB + 1024KB - ) else ( - set spi_size_map=0 - echo spi size: 512KB - echo spi ota map: 256KB + 256KB - ) - ) - ) - ) -) - -echo. -echo start... -echo. - -make clean - -make COMPILE=xcc BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE_MAP=%spi_size_map% - +@echo off + +Rem ******NOTICE****** +Rem MUST set SDK_PATH & BIN_PATH firstly!!! +Rem example: +Rem set SDK_PATH=/c/esp_iot_sdk_freertos +Rem set BIN_PATH=/c/esp8266_bin + +set SDK_PATH="" +set BIN_PATH="" + +echo gen_misc.bat version 20150911 +echo . + +if not %SDK_PATH% == "" ( + echo SDK_PATH: %SDK_PATH% +) else ( + echo ERROR: Please set SDK_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +if not %BIN_PATH% == "" ( + echo BIN_PATH: %BIN_PATH% +) else ( + echo ERROR: Please set BIN_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +echo . +echo Please check SDK_PATH/BIN_PATH, enter (Y/y) to continue: +set input=default +set /p input= + +if not %input% == Y ( + if not %input% == y ( + goto end + ) +) + +echo . +echo Please follow below steps(1-5) to generate specific bin(s): +echo STEP 1: use boot_v1.2+ by default +set boot=new + +echo boot mode: %boot% +echo. + +echo STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin) +set input=default +set /p input=enter (0/1/2, default 0): + +if %input% equ 1 ( + if %boot% equ none ( + set app=0 + echo choose no boot before + echo generate bin: eagle.flash.bin+eagle.irom0text.bin + ) else ( + set app=1 + echo generate bin: user1.bin + ) +) else ( +if %input% equ 2 ( + if %boot% equ none ( + set app=0 + echo choose no boot before + echo generate bin: eagle.flash.bin+eagle.irom0text.bin + ) else ( + set app=2 + echo generate bin: user2.bin + ) +) else ( + if %boot% neq none ( + set boot=none + echo ignore boot + ) + set app=0 + echo generate bin: eagle.flash.bin+eagle.irom0text.bin +)) + +echo. + +echo STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz) +set input=default +set /p input=enter (0/1/2/3, default 2): + +if %input% equ 0 ( + set spi_speed=20 +) else ( +if %input% equ 1 ( + set spi_speed=26.7 +) else ( +if %input% equ 3 ( + set spi_speed=80 +) else ( + set spi_speed=40 +))) + +echo spi speed: %spi_speed% MHz +echo. + +echo STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT) +set input=default +set /p input=enter (0/1/2/3, default 0): + +if %input% equ 1 ( + set spi_mode=QOUT +) else ( +if %input% equ 2 ( + set spi_mode=DIO +) else ( +if %input% equ 3 ( + set spi_mode=DOUT +) else ( + set spi_mode=QIO +))) + +echo spi mode: %spi_mode% +echo. + +echo STEP 5: choose flash size and map +echo 0= 512KB( 256KB+ 256KB) +echo 2=1024KB( 512KB+ 512KB) +echo 3=2048KB( 512KB+ 512KB) +echo 4=4096KB( 512KB+ 512KB) +echo 5=2048KB(1024KB+1024KB) +echo 6=4096KB(1024KB+1024KB) +set input=default +set /p input=enter (0/1/2/3/4/5/6, default 0): + +if %input% equ 2 ( + set spi_size_map=2 + echo spi size: 1024KB + echo spi ota map: 512KB + 512KB +) else ( + if %input% equ 3 ( + set spi_size_map=3 + echo spi size: 2048KB + echo spi ota map: 512KB + 512KB + ) else ( + if %input% equ 4 ( + set spi_size_map=4 + echo spi size: 4096KB + echo spi ota map: 512KB + 512KB + ) else ( + if %input% equ 5 ( + set spi_size_map=5 + echo spi size: 2048KB + echo spi ota map: 1024KB + 1024KB + ) else ( + if %input% equ 6 ( + set spi_size_map=6 + echo spi size: 4096KB + echo spi ota map: 1024KB + 1024KB + ) else ( + set spi_size_map=0 + echo spi size: 512KB + echo spi ota map: 256KB + 256KB + ) + ) + ) + ) +) + +echo. +echo start... +echo. + +make clean + +make COMPILE=xcc BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE_MAP=%spi_size_map% + :end \ No newline at end of file diff --git a/examples/project_template/gen_misc.sh b/examples/project_template/gen_misc.sh old mode 100644 new mode 100755 diff --git a/examples/project_template/include/user_config.h b/examples/project_template/include/user_config.h index 59bce162..50d5f26f 100644 --- a/examples/project_template/include/user_config.h +++ b/examples/project_template/include/user_config.h @@ -1,29 +1,29 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __USER_CONFIG_H__ -#define __USER_CONFIG_H__ - -#endif - +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __USER_CONFIG_H__ +#define __USER_CONFIG_H__ + +#endif + diff --git a/examples/project_template/readme.txt b/examples/project_template/readme.txt index 3c7e7e71..288a84cf 100644 --- a/examples/project_template/readme.txt +++ b/examples/project_template/readme.txt @@ -1,56 +1,56 @@ -This is a simple project template. - -sample_lib is an example for multi-level folder Makefile, notice the folder structure and each Makefile, you can get the clue. - - -HOWTO: -1. Copy this folder to anywhere. -Example: - Copy to ~/workspace/project_template - You can rename this folder as you like. - -2. Export SDK_PATH and BIN_PATH. -Example: - Your SDK path is ~/esp_iot_rtos_sdk, and want generate bin at ~/esp8266_bin. - Do follow steps: - 1>. export SDK_PATH=~/esp_iot_rtos_sdk - 2>. export BIN_PATH=~/esp8266_bin - SDK and project are seperate, you can update SDK without change your project. - -3. Enter project_template folder, run ./gen_misc.sh, and follow the tips and steps. - - -Compile Options: -(1) COMPILE - Possible value: xcc - Default value: - If not set, use gcc by default. - -(2) BOOT - Possible value: none/old/new - none: no need boot - old: use boot_v1.1 - new: use boot_v1.2 - Default value: new - -(3) APP - Possible value: 0/1/2 - 0: original mode, generate eagle.app.v6.flash.bin and eagle.app.v6.irom0text.bin - 1: generate user1 - 2: generate user2 - Default value: 0 - -(3) SPI_SPEED - Possible value: 20/26.7/40/80 - Default value: 40 - -(4) SPI_MODE - Possible value: QIO/QOUT/DIO/DOUT - Default value: QIO - -(4) SPI_SIZE_MAP - Possible value: 0/2/3/4/5/6 - Default value: 0 - -For example: - make COMPILE=gcc BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=0 +This is a simple project template. + +sample_lib is an example for multi-level folder Makefile, notice the folder structure and each Makefile, you can get the clue. + + +HOWTO: +1. Copy this folder to anywhere. +Example: + Copy to ~/workspace/project_template + You can rename this folder as you like. + +2. Export SDK_PATH and BIN_PATH. +Example: + Your SDK path is ~/esp_iot_rtos_sdk, and want generate bin at ~/esp8266_bin. + Do follow steps: + 1>. export SDK_PATH=~/esp_iot_rtos_sdk + 2>. export BIN_PATH=~/esp8266_bin + SDK and project are seperate, you can update SDK without change your project. + +3. Enter project_template folder, run ./gen_misc.sh, and follow the tips and steps. + + +Compile Options: +(1) COMPILE + Possible value: xcc + Default value: + If not set, use gcc by default. + +(2) BOOT + Possible value: none/old/new + none: no need boot + old: use boot_v1.1 + new: use boot_v1.2 + Default value: new + +(3) APP + Possible value: 0/1/2 + 0: original mode, generate eagle.app.v6.flash.bin and eagle.app.v6.irom0text.bin + 1: generate user1 + 2: generate user2 + Default value: 0 + +(3) SPI_SPEED + Possible value: 20/26.7/40/80 + Default value: 40 + +(4) SPI_MODE + Possible value: QIO/QOUT/DIO/DOUT + Default value: QIO + +(4) SPI_SIZE_MAP + Possible value: 0/2/3/4/5/6 + Default value: 0 + +For example: + make COMPILE=gcc BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=0 diff --git a/examples/project_template/sample_lib/Makefile b/examples/project_template/sample_lib/Makefile index 69ce1ed7..f85e2f85 100644 --- a/examples/project_template/sample_lib/Makefile +++ b/examples/project_template/sample_lib/Makefile @@ -1,47 +1,47 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR -UP_EXTRACT_DIR = .. -GEN_LIBS = libsample.a -COMPONENTS_libsample = folder1/libfolder1.a \ - folder2/libfolder2.a -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +UP_EXTRACT_DIR = .. +GEN_LIBS = libsample.a +COMPONENTS_libsample = folder1/libfolder1.a \ + folder2/libfolder2.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/examples/project_template/sample_lib/folder1/Makefile b/examples/project_template/sample_lib/folder1/Makefile index e128f5f0..82e9542f 100644 --- a/examples/project_template/sample_lib/folder1/Makefile +++ b/examples/project_template/sample_lib/folder1/Makefile @@ -1,44 +1,44 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR -GEN_LIBS = libfolder1.a -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +GEN_LIBS = libfolder1.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/examples/project_template/sample_lib/folder2/Makefile b/examples/project_template/sample_lib/folder2/Makefile index 82cbc6c7..8583395b 100644 --- a/examples/project_template/sample_lib/folder2/Makefile +++ b/examples/project_template/sample_lib/folder2/Makefile @@ -1,44 +1,44 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR -GEN_LIBS = libfolder2.a -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +GEN_LIBS = libfolder2.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/examples/project_template/user/Makefile b/examples/project_template/user/Makefile index d57d85da..dd3837c7 100644 --- a/examples/project_template/user/Makefile +++ b/examples/project_template/user/Makefile @@ -1,44 +1,44 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR -GEN_LIBS = libuser.a -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +GEN_LIBS = libuser.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/examples/project_template/user/user_main.c b/examples/project_template/user/user_main.c index d9e6132e..b8f68f48 100644 --- a/examples/project_template/user/user_main.c +++ b/examples/project_template/user/user_main.c @@ -1,81 +1,81 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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. - * - */ - -#include "esp_common.h" - -/****************************************************************************** - * FunctionName : user_rf_cal_sector_set - * Description : SDK just reversed 4 sectors, used for rf init data and paramters. - * We add this function to force users to set rf cal sector, since - * we don't know which sector is free in user's application. - * sector map for last several sectors : ABCCC - * A : rf cal - * B : rf init data - * C : sdk parameters - * Parameters : none - * Returns : rf cal sector -*******************************************************************************/ -uint32 user_rf_cal_sector_set(void) -{ - flash_size_map size_map = system_get_flash_size_map(); - uint32 rf_cal_sec = 0; - - switch (size_map) { - case FLASH_SIZE_4M_MAP_256_256: - rf_cal_sec = 128 - 5; - break; - - case FLASH_SIZE_8M_MAP_512_512: - rf_cal_sec = 256 - 5; - break; - - case FLASH_SIZE_16M_MAP_512_512: - case FLASH_SIZE_16M_MAP_1024_1024: - rf_cal_sec = 512 - 5; - break; - - case FLASH_SIZE_32M_MAP_512_512: - case FLASH_SIZE_32M_MAP_1024_1024: - rf_cal_sec = 1024 - 5; - break; - - default: - rf_cal_sec = 0; - break; - } - - return rf_cal_sec; -} - -/****************************************************************************** - * FunctionName : user_init - * Description : entry of user application, init user function here - * Parameters : none - * Returns : none -*******************************************************************************/ -void user_init(void) -{ - printf("SDK version:%s\n", system_get_sdk_version()); -} - +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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. + * + */ + +#include "esp_common.h" + +/****************************************************************************** + * FunctionName : user_rf_cal_sector_set + * Description : SDK just reversed 4 sectors, used for rf init data and paramters. + * We add this function to force users to set rf cal sector, since + * we don't know which sector is free in user's application. + * sector map for last several sectors : ABCCC + * A : rf cal + * B : rf init data + * C : sdk parameters + * Parameters : none + * Returns : rf cal sector +*******************************************************************************/ +uint32 user_rf_cal_sector_set(void) +{ + flash_size_map size_map = system_get_flash_size_map(); + uint32 rf_cal_sec = 0; + + switch (size_map) { + case FLASH_SIZE_4M_MAP_256_256: + rf_cal_sec = 128 - 5; + break; + + case FLASH_SIZE_8M_MAP_512_512: + rf_cal_sec = 256 - 5; + break; + + case FLASH_SIZE_16M_MAP_512_512: + case FLASH_SIZE_16M_MAP_1024_1024: + rf_cal_sec = 512 - 5; + break; + + case FLASH_SIZE_32M_MAP_512_512: + case FLASH_SIZE_32M_MAP_1024_1024: + rf_cal_sec = 1024 - 5; + break; + + default: + rf_cal_sec = 0; + break; + } + + return rf_cal_sec; +} + +/****************************************************************************** + * FunctionName : user_init + * Description : entry of user application, init user function here + * Parameters : none + * Returns : none +*******************************************************************************/ +void user_init(void) +{ + printf("SDK version:%s\n", system_get_sdk_version()); +} + diff --git a/examples/smart_config/Makefile b/examples/smart_config/Makefile index 79b6d461..ec05f9f1 100644 --- a/examples/smart_config/Makefile +++ b/examples/smart_config/Makefile @@ -1,122 +1,122 @@ -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of object file images to be generated () -# GEN_BINS - list of binaries to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -TARGET = eagle -#FLAVOR = release -FLAVOR = debug - -#EXTRA_CCFLAGS += -u - -ifndef PDIR # { -GEN_IMAGES= eagle.app.v6.out -GEN_BINS= eagle.app.v6.bin -SPECIAL_MKTARGETS=$(APP_MKTARGETS) -SUBDIRS= \ - user - -endif # } PDIR - -LDDIR = $(SDK_PATH)/ld - -CCFLAGS += -Os - -TARGET_LDFLAGS = \ - -nostdlib \ - -Wl,-EL \ - --longcalls \ - --text-section-literals - -ifeq ($(FLAVOR),debug) - TARGET_LDFLAGS += -g -O2 -endif - -ifeq ($(FLAVOR),release) - TARGET_LDFLAGS += -g -O0 -endif - -COMPONENTS_eagle.app.v6 = \ - user/libuser.a - -LINKFLAGS_eagle.app.v6 = \ - -L$(SDK_PATH)/lib \ - -Wl,--gc-sections \ - -nostdlib \ - -T$(LD_FILE) \ - -Wl,--no-check-sections \ - -u call_user_start \ - -Wl,-static \ - -Wl,--start-group \ - -lminic \ - -lgcc \ - -lhal \ - -lphy \ - -lpp \ - -lnet80211 \ - -lwpa \ - -lcrypto \ - -lmain \ - -lfreertos \ - -llwip \ - -lespconn\ - -lsmartconfig \ - -lairkiss\ - $(DEP_LIBS_eagle.app.v6) \ - -Wl,--end-group - -DEPENDS_eagle.app.v6 = \ - $(LD_FILE) \ - $(LDDIR)/eagle.rom.addr.v6.ld - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# - -#UNIVERSAL_TARGET_DEFINES = \ - -# Other potential configuration flags include: -# -DTXRX_TXBUF_DEBUG -# -DTXRX_RXBUF_DEBUG -# -DWLAN_CONFIG_CCX -CONFIGURATION_DEFINES = -DICACHE_FLASH - -DEFINES += \ - $(UNIVERSAL_TARGET_DEFINES) \ - $(CONFIGURATION_DEFINES) - -DDEFINES += \ - $(UNIVERSAL_TARGET_DEFINES) \ - $(CONFIGURATION_DEFINES) - - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -sinclude $(SDK_PATH)/Makefile - -.PHONY: FORCE -FORCE: - +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of object file images to be generated () +# GEN_BINS - list of binaries to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +TARGET = eagle +#FLAVOR = release +FLAVOR = debug + +#EXTRA_CCFLAGS += -u + +ifndef PDIR # { +GEN_IMAGES= eagle.app.v6.out +GEN_BINS= eagle.app.v6.bin +SPECIAL_MKTARGETS=$(APP_MKTARGETS) +SUBDIRS= \ + user + +endif # } PDIR + +LDDIR = $(SDK_PATH)/ld + +CCFLAGS += -Os + +TARGET_LDFLAGS = \ + -nostdlib \ + -Wl,-EL \ + --longcalls \ + --text-section-literals + +ifeq ($(FLAVOR),debug) + TARGET_LDFLAGS += -g -O2 +endif + +ifeq ($(FLAVOR),release) + TARGET_LDFLAGS += -g -O0 +endif + +COMPONENTS_eagle.app.v6 = \ + user/libuser.a + +LINKFLAGS_eagle.app.v6 = \ + -L$(SDK_PATH)/lib \ + -Wl,--gc-sections \ + -nostdlib \ + -T$(LD_FILE) \ + -Wl,--no-check-sections \ + -u call_user_start \ + -Wl,-static \ + -Wl,--start-group \ + -lminic \ + -lgcc \ + -lhal \ + -lphy \ + -lpp \ + -lnet80211 \ + -lwpa \ + -lcrypto \ + -lmain \ + -lfreertos \ + -llwip \ + -lespconn\ + -lsmartconfig \ + -lairkiss\ + $(DEP_LIBS_eagle.app.v6) \ + -Wl,--end-group + +DEPENDS_eagle.app.v6 = \ + $(LD_FILE) \ + $(LDDIR)/eagle.rom.addr.v6.ld + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# + +#UNIVERSAL_TARGET_DEFINES = \ + +# Other potential configuration flags include: +# -DTXRX_TXBUF_DEBUG +# -DTXRX_RXBUF_DEBUG +# -DWLAN_CONFIG_CCX +CONFIGURATION_DEFINES = -DICACHE_FLASH + +DEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + +DDEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +sinclude $(SDK_PATH)/Makefile + +.PHONY: FORCE +FORCE: + diff --git a/examples/smart_config/gen_misc.bat b/examples/smart_config/gen_misc.bat index fd0b44fe..fbb53be7 100644 --- a/examples/smart_config/gen_misc.bat +++ b/examples/smart_config/gen_misc.bat @@ -1,172 +1,172 @@ -@echo off - -Rem ******NOTICE****** -Rem MUST set SDK_PATH & BIN_PATH firstly!!! -Rem example: -Rem set SDK_PATH=/c/esp_iot_sdk_freertos -Rem set BIN_PATH=/c/esp8266_bin - -set SDK_PATH="" -set BIN_PATH="" - -echo gen_misc.bat version 20150911 -echo . - -if not %SDK_PATH% == "" ( - echo SDK_PATH: %SDK_PATH% -) else ( - echo ERROR: Please set SDK_PATH in gen_misc.bat firstly, exit!!! - goto end -) - -if not %BIN_PATH% == "" ( - echo BIN_PATH: %BIN_PATH% -) else ( - echo ERROR: Please set BIN_PATH in gen_misc.bat firstly, exit!!! - goto end -) - -echo . -echo Please check SDK_PATH/BIN_PATH, enter (Y/y) to continue: -set input=default -set /p input= - -if not %input% == Y ( - if not %input% == y ( - goto end - ) -) - -echo . -echo Please follow below steps(1-5) to generate specific bin(s): -echo STEP 1: use boot_v1.2+ by default -set boot=new - -echo boot mode: %boot% -echo. - -echo STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin) -set input=default -set /p input=enter (0/1/2, default 0): - -if %input% equ 1 ( - if %boot% equ none ( - set app=0 - echo choose no boot before - echo generate bin: eagle.flash.bin+eagle.irom0text.bin - ) else ( - set app=1 - echo generate bin: user1.bin - ) -) else ( -if %input% equ 2 ( - if %boot% equ none ( - set app=0 - echo choose no boot before - echo generate bin: eagle.flash.bin+eagle.irom0text.bin - ) else ( - set app=2 - echo generate bin: user2.bin - ) -) else ( - if %boot% neq none ( - set boot=none - echo ignore boot - ) - set app=0 - echo generate bin: eagle.flash.bin+eagle.irom0text.bin -)) - -echo. - -echo STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz) -set input=default -set /p input=enter (0/1/2/3, default 2): - -if %input% equ 0 ( - set spi_speed=20 -) else ( -if %input% equ 1 ( - set spi_speed=26.7 -) else ( -if %input% equ 3 ( - set spi_speed=80 -) else ( - set spi_speed=40 -))) - -echo spi speed: %spi_speed% MHz -echo. - -echo STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT) -set input=default -set /p input=enter (0/1/2/3, default 0): - -if %input% equ 1 ( - set spi_mode=QOUT -) else ( -if %input% equ 2 ( - set spi_mode=DIO -) else ( -if %input% equ 3 ( - set spi_mode=DOUT -) else ( - set spi_mode=QIO -))) - -echo spi mode: %spi_mode% -echo. - -echo STEP 5: choose flash size and map -echo 0= 512KB( 256KB+ 256KB) -echo 2=1024KB( 512KB+ 512KB) -echo 3=2048KB( 512KB+ 512KB) -echo 4=4096KB( 512KB+ 512KB) -echo 5=2048KB(1024KB+1024KB) -echo 6=4096KB(1024KB+1024KB) -set input=default -set /p input=enter (0/1/2/3/4/5/6, default 0): - -if %input% equ 2 ( - set spi_size_map=2 - echo spi size: 1024KB - echo spi ota map: 512KB + 512KB -) else ( - if %input% equ 3 ( - set spi_size_map=3 - echo spi size: 2048KB - echo spi ota map: 512KB + 512KB - ) else ( - if %input% equ 4 ( - set spi_size_map=4 - echo spi size: 4096KB - echo spi ota map: 512KB + 512KB - ) else ( - if %input% equ 5 ( - set spi_size_map=5 - echo spi size: 2048KB - echo spi ota map: 1024KB + 1024KB - ) else ( - if %input% equ 6 ( - set spi_size_map=6 - echo spi size: 4096KB - echo spi ota map: 1024KB + 1024KB - ) else ( - set spi_size_map=0 - echo spi size: 512KB - echo spi ota map: 256KB + 256KB - ) - ) - ) - ) -) - -echo. -echo start... -echo. - -make clean - -make COMPILE=xcc BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE_MAP=%spi_size_map% - +@echo off + +Rem ******NOTICE****** +Rem MUST set SDK_PATH & BIN_PATH firstly!!! +Rem example: +Rem set SDK_PATH=/c/esp_iot_sdk_freertos +Rem set BIN_PATH=/c/esp8266_bin + +set SDK_PATH="" +set BIN_PATH="" + +echo gen_misc.bat version 20150911 +echo . + +if not %SDK_PATH% == "" ( + echo SDK_PATH: %SDK_PATH% +) else ( + echo ERROR: Please set SDK_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +if not %BIN_PATH% == "" ( + echo BIN_PATH: %BIN_PATH% +) else ( + echo ERROR: Please set BIN_PATH in gen_misc.bat firstly, exit!!! + goto end +) + +echo . +echo Please check SDK_PATH/BIN_PATH, enter (Y/y) to continue: +set input=default +set /p input= + +if not %input% == Y ( + if not %input% == y ( + goto end + ) +) + +echo . +echo Please follow below steps(1-5) to generate specific bin(s): +echo STEP 1: use boot_v1.2+ by default +set boot=new + +echo boot mode: %boot% +echo. + +echo STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin) +set input=default +set /p input=enter (0/1/2, default 0): + +if %input% equ 1 ( + if %boot% equ none ( + set app=0 + echo choose no boot before + echo generate bin: eagle.flash.bin+eagle.irom0text.bin + ) else ( + set app=1 + echo generate bin: user1.bin + ) +) else ( +if %input% equ 2 ( + if %boot% equ none ( + set app=0 + echo choose no boot before + echo generate bin: eagle.flash.bin+eagle.irom0text.bin + ) else ( + set app=2 + echo generate bin: user2.bin + ) +) else ( + if %boot% neq none ( + set boot=none + echo ignore boot + ) + set app=0 + echo generate bin: eagle.flash.bin+eagle.irom0text.bin +)) + +echo. + +echo STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz) +set input=default +set /p input=enter (0/1/2/3, default 2): + +if %input% equ 0 ( + set spi_speed=20 +) else ( +if %input% equ 1 ( + set spi_speed=26.7 +) else ( +if %input% equ 3 ( + set spi_speed=80 +) else ( + set spi_speed=40 +))) + +echo spi speed: %spi_speed% MHz +echo. + +echo STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT) +set input=default +set /p input=enter (0/1/2/3, default 0): + +if %input% equ 1 ( + set spi_mode=QOUT +) else ( +if %input% equ 2 ( + set spi_mode=DIO +) else ( +if %input% equ 3 ( + set spi_mode=DOUT +) else ( + set spi_mode=QIO +))) + +echo spi mode: %spi_mode% +echo. + +echo STEP 5: choose flash size and map +echo 0= 512KB( 256KB+ 256KB) +echo 2=1024KB( 512KB+ 512KB) +echo 3=2048KB( 512KB+ 512KB) +echo 4=4096KB( 512KB+ 512KB) +echo 5=2048KB(1024KB+1024KB) +echo 6=4096KB(1024KB+1024KB) +set input=default +set /p input=enter (0/1/2/3/4/5/6, default 0): + +if %input% equ 2 ( + set spi_size_map=2 + echo spi size: 1024KB + echo spi ota map: 512KB + 512KB +) else ( + if %input% equ 3 ( + set spi_size_map=3 + echo spi size: 2048KB + echo spi ota map: 512KB + 512KB + ) else ( + if %input% equ 4 ( + set spi_size_map=4 + echo spi size: 4096KB + echo spi ota map: 512KB + 512KB + ) else ( + if %input% equ 5 ( + set spi_size_map=5 + echo spi size: 2048KB + echo spi ota map: 1024KB + 1024KB + ) else ( + if %input% equ 6 ( + set spi_size_map=6 + echo spi size: 4096KB + echo spi ota map: 1024KB + 1024KB + ) else ( + set spi_size_map=0 + echo spi size: 512KB + echo spi ota map: 256KB + 256KB + ) + ) + ) + ) +) + +echo. +echo start... +echo. + +make clean + +make COMPILE=xcc BOOT=%boot% APP=%app% SPI_SPEED=%spi_speed% SPI_MODE=%spi_mode% SPI_SIZE_MAP=%spi_size_map% + :end \ No newline at end of file diff --git a/examples/smart_config/gen_misc.sh b/examples/smart_config/gen_misc.sh old mode 100644 new mode 100755 diff --git a/examples/smart_config/include/user_config.h b/examples/smart_config/include/user_config.h index 59bce162..50d5f26f 100644 --- a/examples/smart_config/include/user_config.h +++ b/examples/smart_config/include/user_config.h @@ -1,29 +1,29 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __USER_CONFIG_H__ -#define __USER_CONFIG_H__ - -#endif - +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __USER_CONFIG_H__ +#define __USER_CONFIG_H__ + +#endif + diff --git a/examples/smart_config/readme.txt b/examples/smart_config/readme.txt index 6063086a..3f636abe 100644 --- a/examples/smart_config/readme.txt +++ b/examples/smart_config/readme.txt @@ -1,40 +1,40 @@ -1¡¢compile options - -(1) COMPILE - Possible value: xcc - Default value: - If not set, use gcc by default. - -(2) BOOT - Possible value: none/old/new - none: no need boot - old: use boot_v1.1 - new: use boot_v1.2 - Default value: new - -(3) APP - Possible value: 0/1/2 - 0: original mode, generate eagle.app.v6.flash.bin and eagle.app.v6.irom0text.bin - 1: generate user1 - 2: generate user2 - Default value: 0 - -(3) SPI_SPEED - Possible value: 20/26.7/40/80 - Default value: 40 - -(4) SPI_MODE - Possible value: QIO/QOUT/DIO/DOUT - Default value: QIO - -(4) SPI_SIZE_MAP - Possible value: 0/2/3/4/5/6 - Default value: 0 - -For example: - make COMPILE=gcc BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=0 - -2¡¢You can also use gen_misc to make and generate specific bin you needed. - Linux: ./gen_misc.sh - Windows: gen_misc.bat - Follow the tips and steps. +1¡¢compile options + +(1) COMPILE + Possible value: xcc + Default value: + If not set, use gcc by default. + +(2) BOOT + Possible value: none/old/new + none: no need boot + old: use boot_v1.1 + new: use boot_v1.2 + Default value: new + +(3) APP + Possible value: 0/1/2 + 0: original mode, generate eagle.app.v6.flash.bin and eagle.app.v6.irom0text.bin + 1: generate user1 + 2: generate user2 + Default value: 0 + +(3) SPI_SPEED + Possible value: 20/26.7/40/80 + Default value: 40 + +(4) SPI_MODE + Possible value: QIO/QOUT/DIO/DOUT + Default value: QIO + +(4) SPI_SIZE_MAP + Possible value: 0/2/3/4/5/6 + Default value: 0 + +For example: + make COMPILE=gcc BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=0 + +2¡¢You can also use gen_misc to make and generate specific bin you needed. + Linux: ./gen_misc.sh + Windows: gen_misc.bat + Follow the tips and steps. diff --git a/examples/smart_config/user/Makefile b/examples/smart_config/user/Makefile index d57d85da..dd3837c7 100644 --- a/examples/smart_config/user/Makefile +++ b/examples/smart_config/user/Makefile @@ -1,44 +1,44 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR -GEN_LIBS = libuser.a -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +GEN_LIBS = libuser.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/examples/smart_config/user/user_main.c b/examples/smart_config/user/user_main.c index 00ad62c6..531e8d13 100644 --- a/examples/smart_config/user/user_main.c +++ b/examples/smart_config/user/user_main.c @@ -1,267 +1,267 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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. - * - */ - -#include "esp_common.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - -#include "lwip/sockets.h" -#include "lwip/dns.h" -#include "lwip/netdb.h" -#include "espressif/espconn.h" -#include "espressif/airkiss.h" - -#define server_ip "192.168.101.142" -#define server_port 9669 - - -#define DEVICE_TYPE "gh_9e2cff3dfa51" //wechat public number -#define DEVICE_ID "122475" //model ID - -#define DEFAULT_LAN_PORT 12476 - -LOCAL esp_udp ssdp_udp; -LOCAL struct espconn pssdpudpconn; -LOCAL os_timer_t ssdp_time_serv; - -uint8 lan_buf[200]; -uint16 lan_buf_len; -uint8 udp_sent_cnt = 0; - -const airkiss_config_t akconf = -{ - (airkiss_memset_fn)&memset, - (airkiss_memcpy_fn)&memcpy, - (airkiss_memcmp_fn)&memcmp, - 0, -}; - -LOCAL void ICACHE_FLASH_ATTR -airkiss_wifilan_time_callback(void) -{ - uint16 i; - airkiss_lan_ret_t ret; - - if ((udp_sent_cnt++) >30) { - udp_sent_cnt = 0; - os_timer_disarm(&ssdp_time_serv);//s - //return; - } - - ssdp_udp.remote_port = DEFAULT_LAN_PORT; - ssdp_udp.remote_ip[0] = 255; - ssdp_udp.remote_ip[1] = 255; - ssdp_udp.remote_ip[2] = 255; - ssdp_udp.remote_ip[3] = 255; - lan_buf_len = sizeof(lan_buf); - ret = airkiss_lan_pack(AIRKISS_LAN_SSDP_NOTIFY_CMD, - DEVICE_TYPE, DEVICE_ID, 0, 0, lan_buf, &lan_buf_len, &akconf); - if (ret != AIRKISS_LAN_PAKE_READY) { - os_printf("Pack lan packet error!"); - return; - } - - ret = espconn_sendto(&pssdpudpconn, lan_buf, lan_buf_len); - if (ret != 0) { - os_printf("UDP send error!"); - } - os_printf("Finish send notify!\n"); -} - -LOCAL void ICACHE_FLASH_ATTR -airkiss_wifilan_recv_callbk(void *arg, char *pdata, unsigned short len) -{ - uint16 i; - remot_info* pcon_info = NULL; - - airkiss_lan_ret_t ret = airkiss_lan_recv(pdata, len, &akconf); - airkiss_lan_ret_t packret; - - switch (ret){ - case AIRKISS_LAN_SSDP_REQ: - espconn_get_connection_info(&pssdpudpconn, &pcon_info, 0); - os_printf("remote ip: %d.%d.%d.%d \r\n",pcon_info->remote_ip[0],pcon_info->remote_ip[1], - pcon_info->remote_ip[2],pcon_info->remote_ip[3]); - os_printf("remote port: %d \r\n",pcon_info->remote_port); - - pssdpudpconn.proto.udp->remote_port = pcon_info->remote_port; - memcpy(pssdpudpconn.proto.udp->remote_ip,pcon_info->remote_ip,4); - ssdp_udp.remote_port = DEFAULT_LAN_PORT; - - lan_buf_len = sizeof(lan_buf); - packret = airkiss_lan_pack(AIRKISS_LAN_SSDP_RESP_CMD, - DEVICE_TYPE, DEVICE_ID, 0, 0, lan_buf, &lan_buf_len, &akconf); - - if (packret != AIRKISS_LAN_PAKE_READY) { - os_printf("Pack lan packet error!"); - return; - } - - os_printf("\r\n\r\n"); - for (i=0; i + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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. + * + */ + +#include "esp_common.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "lwip/sockets.h" +#include "lwip/dns.h" +#include "lwip/netdb.h" +#include "espressif/espconn.h" +#include "espressif/airkiss.h" + +#define server_ip "192.168.101.142" +#define server_port 9669 + + +#define DEVICE_TYPE "gh_9e2cff3dfa51" //wechat public number +#define DEVICE_ID "122475" //model ID + +#define DEFAULT_LAN_PORT 12476 + +LOCAL esp_udp ssdp_udp; +LOCAL struct espconn pssdpudpconn; +LOCAL os_timer_t ssdp_time_serv; + +uint8 lan_buf[200]; +uint16 lan_buf_len; +uint8 udp_sent_cnt = 0; + +const airkiss_config_t akconf = +{ + (airkiss_memset_fn)&memset, + (airkiss_memcpy_fn)&memcpy, + (airkiss_memcmp_fn)&memcmp, + 0, +}; + +LOCAL void ICACHE_FLASH_ATTR +airkiss_wifilan_time_callback(void) +{ + uint16 i; + airkiss_lan_ret_t ret; + + if ((udp_sent_cnt++) >30) { + udp_sent_cnt = 0; + os_timer_disarm(&ssdp_time_serv);//s + //return; + } + + ssdp_udp.remote_port = DEFAULT_LAN_PORT; + ssdp_udp.remote_ip[0] = 255; + ssdp_udp.remote_ip[1] = 255; + ssdp_udp.remote_ip[2] = 255; + ssdp_udp.remote_ip[3] = 255; + lan_buf_len = sizeof(lan_buf); + ret = airkiss_lan_pack(AIRKISS_LAN_SSDP_NOTIFY_CMD, + DEVICE_TYPE, DEVICE_ID, 0, 0, lan_buf, &lan_buf_len, &akconf); + if (ret != AIRKISS_LAN_PAKE_READY) { + os_printf("Pack lan packet error!"); + return; + } + + ret = espconn_sendto(&pssdpudpconn, lan_buf, lan_buf_len); + if (ret != 0) { + os_printf("UDP send error!"); + } + os_printf("Finish send notify!\n"); +} + +LOCAL void ICACHE_FLASH_ATTR +airkiss_wifilan_recv_callbk(void *arg, char *pdata, unsigned short len) +{ + uint16 i; + remot_info* pcon_info = NULL; + + airkiss_lan_ret_t ret = airkiss_lan_recv(pdata, len, &akconf); + airkiss_lan_ret_t packret; + + switch (ret){ + case AIRKISS_LAN_SSDP_REQ: + espconn_get_connection_info(&pssdpudpconn, &pcon_info, 0); + os_printf("remote ip: %d.%d.%d.%d \r\n",pcon_info->remote_ip[0],pcon_info->remote_ip[1], + pcon_info->remote_ip[2],pcon_info->remote_ip[3]); + os_printf("remote port: %d \r\n",pcon_info->remote_port); + + pssdpudpconn.proto.udp->remote_port = pcon_info->remote_port; + memcpy(pssdpudpconn.proto.udp->remote_ip,pcon_info->remote_ip,4); + ssdp_udp.remote_port = DEFAULT_LAN_PORT; + + lan_buf_len = sizeof(lan_buf); + packret = airkiss_lan_pack(AIRKISS_LAN_SSDP_RESP_CMD, + DEVICE_TYPE, DEVICE_ID, 0, 0, lan_buf, &lan_buf_len, &akconf); + + if (packret != AIRKISS_LAN_PAKE_READY) { + os_printf("Pack lan packet error!"); + return; + } + + os_printf("\r\n\r\n"); + for (i=0; i - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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. - * - */ - -#include "esp_common.h" -#include "user_config.h" - -static os_timer_t timer; - -/****************************************************************************** - * FunctionName : user_rf_cal_sector_set - * Description : SDK just reversed 4 sectors, used for rf init data and paramters. - * We add this function to force users to set rf cal sector, since - * we don't know which sector is free in user's application. - * sector map for last several sectors : ABCCC - * A : rf cal - * B : rf init data - * C : sdk parameters - * Parameters : none - * Returns : rf cal sector -*******************************************************************************/ -uint32 user_rf_cal_sector_set(void) -{ - flash_size_map size_map = system_get_flash_size_map(); - uint32 rf_cal_sec = 0; - - switch (size_map) { - case FLASH_SIZE_4M_MAP_256_256: - rf_cal_sec = 128 - 5; - break; - - case FLASH_SIZE_8M_MAP_512_512: - rf_cal_sec = 256 - 5; - break; - - case FLASH_SIZE_16M_MAP_512_512: - case FLASH_SIZE_16M_MAP_1024_1024: - rf_cal_sec = 512 - 5; - break; - - case FLASH_SIZE_32M_MAP_512_512: - case FLASH_SIZE_32M_MAP_1024_1024: - rf_cal_sec = 1024 - 5; - break; - - default: - rf_cal_sec = 0; - break; - } - - return rf_cal_sec; -} - -LOCAL void ICACHE_FLASH_ATTR wait_for_connection_ready(uint8 flag) -{ - os_timer_disarm(&timer); - if(wifi_station_connected()){ - os_printf("connected\n"); - } else { - os_printf("reconnect after 2s\n"); - os_timer_setfn(&timer, (os_timer_func_t *)wait_for_connection_ready, NULL); - os_timer_arm(&timer, 2000, 0); - } -} - -LOCAL void ICACHE_FLASH_ATTR on_wifi_connect(){ - os_timer_disarm(&timer); - os_timer_setfn(&timer, (os_timer_func_t *)wait_for_connection_ready, NULL); - os_timer_arm(&timer, 100, 0); -} - -LOCAL void ICACHE_FLASH_ATTR on_wifi_disconnect(uint8_t reason){ - os_printf("disconnect %d\n", reason); -} - -/****************************************************************************** - * FunctionName : user_init - * Description : entry of user application, init user function here - * Parameters : none - * Returns : none -*******************************************************************************/ -void user_init(void) -{ - printf("SDK version:%s\n", system_get_sdk_version()); - - set_on_station_connect(on_wifi_connect); - set_on_station_disconnect(on_wifi_disconnect); - init_esp_wifi(); - stop_wifi_ap(); - start_wifi_station(SSID, PASSWORD); -} +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2017 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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. + * + */ + +#include "esp_common.h" +#include "user_config.h" + +static os_timer_t timer; + +/****************************************************************************** + * FunctionName : user_rf_cal_sector_set + * Description : SDK just reversed 4 sectors, used for rf init data and paramters. + * We add this function to force users to set rf cal sector, since + * we don't know which sector is free in user's application. + * sector map for last several sectors : ABCCC + * A : rf cal + * B : rf init data + * C : sdk parameters + * Parameters : none + * Returns : rf cal sector +*******************************************************************************/ +uint32 user_rf_cal_sector_set(void) +{ + flash_size_map size_map = system_get_flash_size_map(); + uint32 rf_cal_sec = 0; + + switch (size_map) { + case FLASH_SIZE_4M_MAP_256_256: + rf_cal_sec = 128 - 5; + break; + + case FLASH_SIZE_8M_MAP_512_512: + rf_cal_sec = 256 - 5; + break; + + case FLASH_SIZE_16M_MAP_512_512: + case FLASH_SIZE_16M_MAP_1024_1024: + rf_cal_sec = 512 - 5; + break; + + case FLASH_SIZE_32M_MAP_512_512: + case FLASH_SIZE_32M_MAP_1024_1024: + rf_cal_sec = 1024 - 5; + break; + + default: + rf_cal_sec = 0; + break; + } + + return rf_cal_sec; +} + +LOCAL void ICACHE_FLASH_ATTR wait_for_connection_ready(uint8 flag) +{ + os_timer_disarm(&timer); + if(wifi_station_connected()){ + os_printf("connected\n"); + } else { + os_printf("reconnect after 2s\n"); + os_timer_setfn(&timer, (os_timer_func_t *)wait_for_connection_ready, NULL); + os_timer_arm(&timer, 2000, 0); + } +} + +LOCAL void ICACHE_FLASH_ATTR on_wifi_connect(){ + os_timer_disarm(&timer); + os_timer_setfn(&timer, (os_timer_func_t *)wait_for_connection_ready, NULL); + os_timer_arm(&timer, 100, 0); +} + +LOCAL void ICACHE_FLASH_ATTR on_wifi_disconnect(uint8_t reason){ + os_printf("disconnect %d\n", reason); +} + +/****************************************************************************** + * FunctionName : user_init + * Description : entry of user application, init user function here + * Parameters : none + * Returns : none +*******************************************************************************/ +void user_init(void) +{ + printf("SDK version:%s\n", system_get_sdk_version()); + + set_on_station_connect(on_wifi_connect); + set_on_station_disconnect(on_wifi_disconnect); + init_esp_wifi(); + stop_wifi_ap(); + start_wifi_station(SSID, PASSWORD); +} diff --git a/examples/wps_demo/readme.txt b/examples/wps_demo/readme.txt index e0588e33..288a84cf 100644 --- a/examples/wps_demo/readme.txt +++ b/examples/wps_demo/readme.txt @@ -1,4 +1,4 @@ -This is a simple project template. +This is a simple project template. sample_lib is an example for multi-level folder Makefile, notice the folder structure and each Makefile, you can get the clue. diff --git a/extra_include/xtensa/cacheasm.h b/extra_include/xtensa/cacheasm.h index 7111fec1..e3d47a84 100644 --- a/extra_include/xtensa/cacheasm.h +++ b/extra_include/xtensa/cacheasm.h @@ -1,807 +1,807 @@ -/* - * xtensa/cacheasm.h -- assembler-specific cache related definitions - * that depend on CORE configuration - * - * This file is logically part of xtensa/coreasm.h , - * but is kept separate for modularity / compilation-performance. - */ - -/* - * Copyright (c) 2001-2002, 2006 Tensilica Inc. - * - * 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 XTENSA_CACHEASM_H -#define XTENSA_CACHEASM_H - -#include -#include - -/* - * This header file defines assembler macros of the form: - * cache_ - * where is 'i' or 'd' for instruction and data caches, - * and indicates the function of the macro. - * - * The following functions are defined, - * and apply only to the specified cache (I or D): - * - * reset - * Resets the cache. - * - * sync - * Makes sure any previous cache instructions have been completed; - * ie. makes sure any previous cache control operations - * have had full effect and been synchronized to memory. - * Eg. any invalidate completed [so as not to generate a hit], - * any writebacks or other pipelined writes written to memory, etc. - * - * invalidate_line (single cache line) - * invalidate_region (specified memory range) - * invalidate_all (entire cache) - * Invalidates all cache entries that cache - * data from the specified memory range. - * NOTE: locked entries are not invalidated. - * - * writeback_line (single cache line) - * writeback_region (specified memory range) - * writeback_all (entire cache) - * Writes back to memory all dirty cache entries - * that cache data from the specified memory range, - * and marks these entries as clean. - * NOTE: on some future implementations, this might - * also invalidate. - * NOTE: locked entries are written back, but never invalidated. - * NOTE: instruction caches never implement writeback. - * - * writeback_inv_line (single cache line) - * writeback_inv_region (specified memory range) - * writeback_inv_all (entire cache) - * Writes back to memory all dirty cache entries - * that cache data from the specified memory range, - * and invalidates these entries (including all clean - * cache entries that cache data from that range). - * NOTE: locked entries are written back but not invalidated. - * NOTE: instruction caches never implement writeback. - * - * lock_line (single cache line) - * lock_region (specified memory range) - * Prefetch and lock the specified memory range into cache. - * NOTE: if any part of the specified memory range cannot - * be locked, a Load/Store Error (for dcache) or Instruction - * Fetch Error (for icache) exception occurs. These macros don't - * do anything special (yet anyway) to handle this situation. - * - * unlock_line (single cache line) - * unlock_region (specified memory range) - * unlock_all (entire cache) - * Unlock cache entries that cache the specified memory range. - * Entries not already locked are unaffected. - * - * coherence_on - * coherence_off - * Turn off and on cache coherence - * - */ - - - -/*************************** GENERIC -- ALL CACHES ***************************/ - - -/* - * The following macros assume the following cache size/parameter limits - * in the current Xtensa core implementation: - * cache size: 1024 bytes minimum - * line size: 16 - 64 bytes - * way count: 1 - 4 - * - * Minimum entries per way (ie. per associativity) = 1024 / 64 / 4 = 4 - * Hence the assumption that each loop can execute four cache instructions. - * - * Correspondingly, the offset range of instructions is assumed able to cover - * four lines, ie. offsets {0,1,2,3} * line_size are assumed valid for - * both hit and indexed cache instructions. Ie. these offsets are all - * valid: 0, 16, 32, 48, 64, 96, 128, 192 (for line sizes 16, 32, 64). - * This is true of all original cache instructions - * (dhi, ihi, dhwb, dhwbi, dii, iii) which have offsets - * of 0 to 1020 in multiples of 4 (ie. 8 bits shifted by 2). - * This is also true of subsequent cache instructions - * (dhu, ihu, diu, iiu, diwb, diwbi, dpfl, ipfl) which have offsets - * of 0 to 240 in multiples of 16 (ie. 4 bits shifted by 4). - * - * (Maximum cache size, currently 32k, doesn't affect the following macros. - * Cache ways > MMU min page size cause aliasing but that's another matter.) - */ - - - -/* - * Macro to apply an 'indexed' cache instruction to the entire cache. - * - * Parameters: - * cainst instruction/ that takes an address register parameter - * and an offset parameter (in range 0 .. 3*linesize). - * size size of cache in bytes - * linesize size of cache line in bytes (always power-of-2) - * assoc_or1 number of associativities (ways/sets) in cache - * if all sets affected by cainst, - * or 1 if only one set (or not all sets) of the cache - * is affected by cainst (eg. DIWB or DIWBI [not yet ISA defined]). - * aa, ab unique address registers (temporaries) - * loopokay 1 (default) allows use of zero-overhead loops, 0 does not - * immrange range (max value) of cainst's immediate offset parameter, in bytes - * (NOTE: macro assumes immrange allows power-of-2 number of lines) - */ - - .macro cache_index_all cainst, size, linesize, assoc_or1, aa, ab, loopokay=1, maxofs=240 - - // Number of indices in cache (lines per way): - .set .Lindices, (\size / (\linesize * \assoc_or1)) - // Number of indices processed per loop iteration (max 4): - .set .Lperloop, .Lindices - .ifgt .Lperloop - 4 - .set .Lperloop, 4 - .endif - // Also limit instructions per loop if cache line size exceeds immediate range: - .set .Lmaxperloop, (\maxofs / \linesize) + 1 - .ifgt .Lperloop - .Lmaxperloop - .set .Lperloop, .Lmaxperloop - .endif - // Avoid addi of 128 which takes two instructions (addmi,addi): - .ifeq .Lperloop*\linesize - 128 - .ifgt .Lperloop - 1 - .set .Lperloop, .Lperloop / 2 - .endif - .endif - - // \size byte cache, \linesize byte lines, \assoc_or1 way(s) affected by each \cainst. - .ifne (\loopokay & XCHAL_HAVE_LOOPS) - - movi \aa, .Lindices / .Lperloop // number of loop iterations - // Possible improvement: need only loop if \aa > 1 ; - // however \aa == 1 is highly unlikely. - movi \ab, 0 // to iterate over cache - loop \aa, .Lend_cachex\@ - .set .Li, 0 ; .rept .Lperloop - \cainst \ab, .Li*\linesize - .set .Li, .Li+1 ; .endr - addi \ab, \ab, .Lperloop*\linesize // move to next line -.Lend_cachex\@: - - .else - - movi \aa, (\size / \assoc_or1) - // Possible improvement: need only loop if \aa > 1 ; - // however \aa == 1 is highly unlikely. - movi \ab, 0 // to iterate over cache -.Lstart_cachex\@: - .set .Li, 0 ; .rept .Lperloop - \cainst \ab, .Li*\linesize - .set .Li, .Li+1 ; .endr - addi \ab, \ab, .Lperloop*\linesize // move to next line - bltu \ab, \aa, .Lstart_cachex\@ - - .endif - - .endm - - -/* - * Macro to apply a 'hit' cache instruction to a memory region, - * ie. to any cache entries that cache a specified portion (region) of memory. - * Takes care of the unaligned cases, ie. may apply to one - * more cache line than $asize / lineSize if $aaddr is not aligned. - * - * - * Parameters are: - * cainst instruction/macro that takes an address register parameter - * and an offset parameter (currently always zero) - * and generates a cache instruction (eg. "dhi", "dhwb", "ihi", etc.) - * linesize_log2 log2(size of cache line in bytes) - * addr register containing start address of region (clobbered) - * asize register containing size of the region in bytes (clobbered) - * askew unique register used as temporary - * - * Note: A possible optimization to this macro is to apply the operation - * to the entire cache if the region exceeds the size of the cache - * by some empirically determined amount or factor. Some experimentation - * is required to determine the appropriate factors, which also need - * to be tunable if required. - */ - - .macro cache_hit_region cainst, linesize_log2, addr, asize, askew - - // Make \asize the number of iterations: - extui \askew, \addr, 0, \linesize_log2 // get unalignment amount of \addr - add \asize, \asize, \askew // ... and add it to \asize - addi \asize, \asize, (1 << \linesize_log2) - 1 // round up! - srli \asize, \asize, \linesize_log2 - - // Iterate over region: - floopnez \asize, cacheh\@ - \cainst \addr, 0 - addi \addr, \addr, (1 << \linesize_log2) // move to next line - floopend \asize, cacheh\@ - - .endm - - - - - -/*************************** INSTRUCTION CACHE ***************************/ - - -/* - * Reset/initialize the instruction cache by simply invalidating it: - * (need to unlock first also, if cache locking implemented): - * - * Parameters: - * aa, ab unique address registers (temporaries) - */ - .macro icache_reset aa, ab, loopokay=0 - icache_unlock_all \aa, \ab, \loopokay - icache_invalidate_all \aa, \ab, \loopokay - .endm - - -/* - * Synchronize after an instruction cache operation, - * to be sure everything is in sync with memory as to be - * expected following any previous instruction cache control operations. - * - * Even if a config doesn't have caches, an isync is still needed - * when instructions in any memory are modified, whether by a loader - * or self-modifying code. Therefore, this macro always produces - * an isync, whether or not an icache is present. - * - * Parameters are: - * ar an address register (temporary) (currently unused, but may be used in future) - */ - .macro icache_sync ar - isync - .endm - - - -/* - * Invalidate a single line of the instruction cache. - * Parameters are: - * ar address register that contains (virtual) address to invalidate - * (may get clobbered in a future implementation, but not currently) - * offset (optional) offset to add to \ar to compute effective address to invalidate - * (note: some number of lsbits are ignored) - */ - .macro icache_invalidate_line ar, offset -#if XCHAL_ICACHE_SIZE > 0 - ihi \ar, \offset // invalidate icache line - /* - * NOTE: in some early version of a test chip silicon (SiChip1), - * 'ihi' didn't work, so software had to replace it with - * the much more draconian 'iii' - * (which would just invalidate more than it should, - * which should be okay other than the performance hit - * because cache locking did not exist in that version, - * unless user somehow relies on something being cached). - * - * #if ... targeting this ancient, now non-existent, test chip silicon ... - * iii \ar, \offset - * #endif - */ - icache_sync \ar -#endif - .endm - - - - -/* - * Invalidate instruction cache entries that cache a specified portion of memory. - * Parameters are: - * astart start address (register gets clobbered) - * asize size of the region in bytes (register gets clobbered) - * ac unique register used as temporary - */ - .macro icache_invalidate_region astart, asize, ac -#if XCHAL_ICACHE_SIZE > 0 - // Instruction cache region invalidation: - cache_hit_region ihi, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac - icache_sync \ac - // End of instruction cache region invalidation -#endif - .endm - - - -/* - * Invalidate entire instruction cache. - * - * Parameters: - * aa, ab unique address registers (temporaries) - */ - .macro icache_invalidate_all aa, ab, loopokay=1 -#if XCHAL_ICACHE_SIZE > 0 - // Instruction cache invalidation: - cache_index_all iii, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, XCHAL_ICACHE_WAYS, \aa, \ab, \loopokay, 1020 - icache_sync \aa - // End of instruction cache invalidation -#endif - .endm - - - -/* - * Lock (prefetch & lock) a single line of the instruction cache. - * - * Parameters are: - * ar address register that contains (virtual) address to lock - * (may get clobbered in a future implementation, but not currently) - * offset offset to add to \ar to compute effective address to lock - * (note: some number of lsbits are ignored) - */ - .macro icache_lock_line ar, offset -#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE - ipfl \ar, \offset /* prefetch and lock icache line */ - icache_sync \ar -#endif - .endm - - - -/* - * Lock (prefetch & lock) a specified portion of memory into the instruction cache. - * Parameters are: - * astart start address (register gets clobbered) - * asize size of the region in bytes (register gets clobbered) - * ac unique register used as temporary - */ - .macro icache_lock_region astart, asize, ac -#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE - // Instruction cache region lock: - cache_hit_region ipfl, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac - icache_sync \ac - // End of instruction cache region lock -#endif - .endm - - - -/* - * Unlock a single line of the instruction cache. - * - * Parameters are: - * ar address register that contains (virtual) address to unlock - * (may get clobbered in a future implementation, but not currently) - * offset offset to add to \ar to compute effective address to unlock - * (note: some number of lsbits are ignored) - */ - .macro icache_unlock_line ar, offset -#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE - ihu \ar, \offset /* unlock icache line */ - icache_sync \ar -#endif - .endm - - - -/* - * Unlock a specified portion of memory from the instruction cache. - * Parameters are: - * astart start address (register gets clobbered) - * asize size of the region in bytes (register gets clobbered) - * ac unique register used as temporary - */ - .macro icache_unlock_region astart, asize, ac -#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE - // Instruction cache region unlock: - cache_hit_region ihu, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac - icache_sync \ac - // End of instruction cache region unlock -#endif - .endm - - - -/* - * Unlock entire instruction cache. - * - * Parameters: - * aa, ab unique address registers (temporaries) - */ - .macro icache_unlock_all aa, ab, loopokay=1 -#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE - // Instruction cache unlock: - cache_index_all iiu, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, 1, \aa, \ab, \loopokay - icache_sync \aa - // End of instruction cache unlock -#endif - .endm - - - - - -/*************************** DATA CACHE ***************************/ - - - -/* - * Reset/initialize the data cache by simply invalidating it - * (need to unlock first also, if cache locking implemented): - * - * Parameters: - * aa, ab unique address registers (temporaries) - */ - .macro dcache_reset aa, ab, loopokay=0 - dcache_unlock_all \aa, \ab, \loopokay - dcache_invalidate_all \aa, \ab, \loopokay - .endm - - - - -/* - * Synchronize after a data cache operation, - * to be sure everything is in sync with memory as to be - * expected following any previous data cache control operations. - * - * Parameters are: - * ar an address register (temporary) (currently unused, but may be used in future) - */ - .macro dcache_sync ar -#if XCHAL_DCACHE_SIZE > 0 - // This previous sequence errs on the conservative side (too much so); a DSYNC should be sufficient: - //memw // synchronize data cache changes relative to subsequent memory accesses - //isync // be conservative and ISYNC as well (just to be sure) - - dsync -#endif - .endm - - - -/* - * Opt into cache coherence. - * - * Parameters are: - * ar,at two scratch address registers (both clobbered) - */ - .macro cache_coherence_on ar at -#if XCHAL_HAVE_EXTERN_REGS && XCHAL_DCACHE_IS_COHERENT - movi \ar, 1 - movi \at, XER_CCON - wer \ar, \at - extw -# endif - .endm - - - -/* - * Opt out of cache coherence. - * NOTE: this is generally preceded by emptying the cache; - * see xthal_cache_coherence_optout() in hal/coherence.c for details. - * - * Parameters are: - * ar,at two scratch address registers (both clobbered) - */ - .macro cache_coherence_off ar at -#if XCHAL_HAVE_EXTERN_REGS && XCHAL_DCACHE_IS_COHERENT - extw - movi \at, 0 - movi \ar, XER_CCON - wer \at, \ar - extw -#endif - .endm - - - -/* - * Synchronize after a data store operation, - * to be sure the stored data is completely off the processor - * (and assuming there is no buffering outside the processor, - * that the data is in memory). This may be required to - * ensure that the processor's write buffers are emptied. - * A MEMW followed by a read guarantees this, by definition. - * We also try to make sure the read itself completes. - * - * Parameters are: - * ar an address register (temporary) - */ - .macro write_sync ar - memw // ensure previous memory accesses are complete prior to subsequent memory accesses - l32i \ar, sp, 0 // completing this read ensures any previous write has completed, because of MEMW - //slot - add \ar, \ar, \ar // use the result of the read to help ensure the read completes (in future architectures) - .endm - - -/* - * Invalidate a single line of the data cache. - * Parameters are: - * ar address register that contains (virtual) address to invalidate - * (may get clobbered in a future implementation, but not currently) - * offset (optional) offset to add to \ar to compute effective address to invalidate - * (note: some number of lsbits are ignored) - */ - .macro dcache_invalidate_line ar, offset -#if XCHAL_DCACHE_SIZE > 0 - dhi \ar, \offset - dcache_sync \ar -#endif - .endm - - - - - -/* - * Invalidate data cache entries that cache a specified portion of memory. - * Parameters are: - * astart start address (register gets clobbered) - * asize size of the region in bytes (register gets clobbered) - * ac unique register used as temporary - */ - .macro dcache_invalidate_region astart, asize, ac -#if XCHAL_DCACHE_SIZE > 0 - // Data cache region invalidation: - cache_hit_region dhi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac - dcache_sync \ac - // End of data cache region invalidation -#endif - .endm - - - -#if 0 -/* - * This is a work-around for a bug in SiChip1. - * To enable the work-around, uncomment this and replace 'dii' - * with 'dii_s1' everywhere, eg. in the dcache_invalidate_all - * macro below. - */ - .macro dii_s1 ar, offset - dii \ar, \offset - or \ar, \ar, \ar - or \ar, \ar, \ar - or \ar, \ar, \ar - or \ar, \ar, \ar - .endm -#endif - - -/* - * Invalidate entire data cache. - * - * Parameters: - * aa, ab unique address registers (temporaries) - */ - .macro dcache_invalidate_all aa, ab, loopokay=1 -#if XCHAL_DCACHE_SIZE > 0 - // Data cache invalidation: - cache_index_all dii, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, XCHAL_DCACHE_WAYS, \aa, \ab, \loopokay, 1020 - dcache_sync \aa - // End of data cache invalidation -#endif - .endm - - - -/* - * Writeback a single line of the data cache. - * Parameters are: - * ar address register that contains (virtual) address to writeback - * (may get clobbered in a future implementation, but not currently) - * offset offset to add to \ar to compute effective address to writeback - * (note: some number of lsbits are ignored) - */ - .macro dcache_writeback_line ar, offset -#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK - dhwb \ar, \offset - dcache_sync \ar -#endif - .endm - - - -/* - * Writeback dirty data cache entries that cache a specified portion of memory. - * Parameters are: - * astart start address (register gets clobbered) - * asize size of the region in bytes (register gets clobbered) - * ac unique register used as temporary - */ - .macro dcache_writeback_region astart, asize, ac -#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK - // Data cache region writeback: - cache_hit_region dhwb, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac - dcache_sync \ac - // End of data cache region writeback -#endif - .endm - - - -/* - * Writeback entire data cache. - * Parameters: - * aa, ab unique address registers (temporaries) - */ - .macro dcache_writeback_all aa, ab, loopokay=1 -#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK - // Data cache writeback: - cache_index_all diwb, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay - dcache_sync \aa - // End of data cache writeback -#endif - .endm - - - -/* - * Writeback and invalidate a single line of the data cache. - * Parameters are: - * ar address register that contains (virtual) address to writeback and invalidate - * (may get clobbered in a future implementation, but not currently) - * offset offset to add to \ar to compute effective address to writeback and invalidate - * (note: some number of lsbits are ignored) - */ - .macro dcache_writeback_inv_line ar, offset -#if XCHAL_DCACHE_SIZE > 0 - dhwbi \ar, \offset /* writeback and invalidate dcache line */ - dcache_sync \ar -#endif - .endm - - - -/* - * Writeback and invalidate data cache entries that cache a specified portion of memory. - * Parameters are: - * astart start address (register gets clobbered) - * asize size of the region in bytes (register gets clobbered) - * ac unique register used as temporary - */ - .macro dcache_writeback_inv_region astart, asize, ac -#if XCHAL_DCACHE_SIZE > 0 - // Data cache region writeback and invalidate: - cache_hit_region dhwbi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac - dcache_sync \ac - // End of data cache region writeback and invalidate -#endif - .endm - - - -/* - * Writeback and invalidate entire data cache. - * Parameters: - * aa, ab unique address registers (temporaries) - */ - .macro dcache_writeback_inv_all aa, ab, loopokay=1 -#if XCHAL_DCACHE_SIZE > 0 - // Data cache writeback and invalidate: -#if XCHAL_DCACHE_IS_WRITEBACK - cache_index_all diwbi, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay - dcache_sync \aa -#else /*writeback*/ - // Data cache does not support writeback, so just invalidate: */ - dcache_invalidate_all \aa, \ab, \loopokay -#endif /*writeback*/ - // End of data cache writeback and invalidate -#endif - .endm - - - - -/* - * Lock (prefetch & lock) a single line of the data cache. - * - * Parameters are: - * ar address register that contains (virtual) address to lock - * (may get clobbered in a future implementation, but not currently) - * offset offset to add to \ar to compute effective address to lock - * (note: some number of lsbits are ignored) - */ - .macro dcache_lock_line ar, offset -#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE - dpfl \ar, \offset /* prefetch and lock dcache line */ - dcache_sync \ar -#endif - .endm - - - -/* - * Lock (prefetch & lock) a specified portion of memory into the data cache. - * Parameters are: - * astart start address (register gets clobbered) - * asize size of the region in bytes (register gets clobbered) - * ac unique register used as temporary - */ - .macro dcache_lock_region astart, asize, ac -#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE - // Data cache region lock: - cache_hit_region dpfl, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac - dcache_sync \ac - // End of data cache region lock -#endif - .endm - - - -/* - * Unlock a single line of the data cache. - * - * Parameters are: - * ar address register that contains (virtual) address to unlock - * (may get clobbered in a future implementation, but not currently) - * offset offset to add to \ar to compute effective address to unlock - * (note: some number of lsbits are ignored) - */ - .macro dcache_unlock_line ar, offset -#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE - dhu \ar, \offset /* unlock dcache line */ - dcache_sync \ar -#endif - .endm - - - -/* - * Unlock a specified portion of memory from the data cache. - * Parameters are: - * astart start address (register gets clobbered) - * asize size of the region in bytes (register gets clobbered) - * ac unique register used as temporary - */ - .macro dcache_unlock_region astart, asize, ac -#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE - // Data cache region unlock: - cache_hit_region dhu, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac - dcache_sync \ac - // End of data cache region unlock -#endif - .endm - - - -/* - * Unlock entire data cache. - * - * Parameters: - * aa, ab unique address registers (temporaries) - */ - .macro dcache_unlock_all aa, ab, loopokay=1 -#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE - // Data cache unlock: - cache_index_all diu, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay - dcache_sync \aa - // End of data cache unlock -#endif - .endm - - -#endif /*XTENSA_CACHEASM_H*/ - +/* + * xtensa/cacheasm.h -- assembler-specific cache related definitions + * that depend on CORE configuration + * + * This file is logically part of xtensa/coreasm.h , + * but is kept separate for modularity / compilation-performance. + */ + +/* + * Copyright (c) 2001-2002, 2006 Tensilica Inc. + * + * 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 XTENSA_CACHEASM_H +#define XTENSA_CACHEASM_H + +#include +#include + +/* + * This header file defines assembler macros of the form: + * cache_ + * where is 'i' or 'd' for instruction and data caches, + * and indicates the function of the macro. + * + * The following functions are defined, + * and apply only to the specified cache (I or D): + * + * reset + * Resets the cache. + * + * sync + * Makes sure any previous cache instructions have been completed; + * ie. makes sure any previous cache control operations + * have had full effect and been synchronized to memory. + * Eg. any invalidate completed [so as not to generate a hit], + * any writebacks or other pipelined writes written to memory, etc. + * + * invalidate_line (single cache line) + * invalidate_region (specified memory range) + * invalidate_all (entire cache) + * Invalidates all cache entries that cache + * data from the specified memory range. + * NOTE: locked entries are not invalidated. + * + * writeback_line (single cache line) + * writeback_region (specified memory range) + * writeback_all (entire cache) + * Writes back to memory all dirty cache entries + * that cache data from the specified memory range, + * and marks these entries as clean. + * NOTE: on some future implementations, this might + * also invalidate. + * NOTE: locked entries are written back, but never invalidated. + * NOTE: instruction caches never implement writeback. + * + * writeback_inv_line (single cache line) + * writeback_inv_region (specified memory range) + * writeback_inv_all (entire cache) + * Writes back to memory all dirty cache entries + * that cache data from the specified memory range, + * and invalidates these entries (including all clean + * cache entries that cache data from that range). + * NOTE: locked entries are written back but not invalidated. + * NOTE: instruction caches never implement writeback. + * + * lock_line (single cache line) + * lock_region (specified memory range) + * Prefetch and lock the specified memory range into cache. + * NOTE: if any part of the specified memory range cannot + * be locked, a Load/Store Error (for dcache) or Instruction + * Fetch Error (for icache) exception occurs. These macros don't + * do anything special (yet anyway) to handle this situation. + * + * unlock_line (single cache line) + * unlock_region (specified memory range) + * unlock_all (entire cache) + * Unlock cache entries that cache the specified memory range. + * Entries not already locked are unaffected. + * + * coherence_on + * coherence_off + * Turn off and on cache coherence + * + */ + + + +/*************************** GENERIC -- ALL CACHES ***************************/ + + +/* + * The following macros assume the following cache size/parameter limits + * in the current Xtensa core implementation: + * cache size: 1024 bytes minimum + * line size: 16 - 64 bytes + * way count: 1 - 4 + * + * Minimum entries per way (ie. per associativity) = 1024 / 64 / 4 = 4 + * Hence the assumption that each loop can execute four cache instructions. + * + * Correspondingly, the offset range of instructions is assumed able to cover + * four lines, ie. offsets {0,1,2,3} * line_size are assumed valid for + * both hit and indexed cache instructions. Ie. these offsets are all + * valid: 0, 16, 32, 48, 64, 96, 128, 192 (for line sizes 16, 32, 64). + * This is true of all original cache instructions + * (dhi, ihi, dhwb, dhwbi, dii, iii) which have offsets + * of 0 to 1020 in multiples of 4 (ie. 8 bits shifted by 2). + * This is also true of subsequent cache instructions + * (dhu, ihu, diu, iiu, diwb, diwbi, dpfl, ipfl) which have offsets + * of 0 to 240 in multiples of 16 (ie. 4 bits shifted by 4). + * + * (Maximum cache size, currently 32k, doesn't affect the following macros. + * Cache ways > MMU min page size cause aliasing but that's another matter.) + */ + + + +/* + * Macro to apply an 'indexed' cache instruction to the entire cache. + * + * Parameters: + * cainst instruction/ that takes an address register parameter + * and an offset parameter (in range 0 .. 3*linesize). + * size size of cache in bytes + * linesize size of cache line in bytes (always power-of-2) + * assoc_or1 number of associativities (ways/sets) in cache + * if all sets affected by cainst, + * or 1 if only one set (or not all sets) of the cache + * is affected by cainst (eg. DIWB or DIWBI [not yet ISA defined]). + * aa, ab unique address registers (temporaries) + * loopokay 1 (default) allows use of zero-overhead loops, 0 does not + * immrange range (max value) of cainst's immediate offset parameter, in bytes + * (NOTE: macro assumes immrange allows power-of-2 number of lines) + */ + + .macro cache_index_all cainst, size, linesize, assoc_or1, aa, ab, loopokay=1, maxofs=240 + + // Number of indices in cache (lines per way): + .set .Lindices, (\size / (\linesize * \assoc_or1)) + // Number of indices processed per loop iteration (max 4): + .set .Lperloop, .Lindices + .ifgt .Lperloop - 4 + .set .Lperloop, 4 + .endif + // Also limit instructions per loop if cache line size exceeds immediate range: + .set .Lmaxperloop, (\maxofs / \linesize) + 1 + .ifgt .Lperloop - .Lmaxperloop + .set .Lperloop, .Lmaxperloop + .endif + // Avoid addi of 128 which takes two instructions (addmi,addi): + .ifeq .Lperloop*\linesize - 128 + .ifgt .Lperloop - 1 + .set .Lperloop, .Lperloop / 2 + .endif + .endif + + // \size byte cache, \linesize byte lines, \assoc_or1 way(s) affected by each \cainst. + .ifne (\loopokay & XCHAL_HAVE_LOOPS) + + movi \aa, .Lindices / .Lperloop // number of loop iterations + // Possible improvement: need only loop if \aa > 1 ; + // however \aa == 1 is highly unlikely. + movi \ab, 0 // to iterate over cache + loop \aa, .Lend_cachex\@ + .set .Li, 0 ; .rept .Lperloop + \cainst \ab, .Li*\linesize + .set .Li, .Li+1 ; .endr + addi \ab, \ab, .Lperloop*\linesize // move to next line +.Lend_cachex\@: + + .else + + movi \aa, (\size / \assoc_or1) + // Possible improvement: need only loop if \aa > 1 ; + // however \aa == 1 is highly unlikely. + movi \ab, 0 // to iterate over cache +.Lstart_cachex\@: + .set .Li, 0 ; .rept .Lperloop + \cainst \ab, .Li*\linesize + .set .Li, .Li+1 ; .endr + addi \ab, \ab, .Lperloop*\linesize // move to next line + bltu \ab, \aa, .Lstart_cachex\@ + + .endif + + .endm + + +/* + * Macro to apply a 'hit' cache instruction to a memory region, + * ie. to any cache entries that cache a specified portion (region) of memory. + * Takes care of the unaligned cases, ie. may apply to one + * more cache line than $asize / lineSize if $aaddr is not aligned. + * + * + * Parameters are: + * cainst instruction/macro that takes an address register parameter + * and an offset parameter (currently always zero) + * and generates a cache instruction (eg. "dhi", "dhwb", "ihi", etc.) + * linesize_log2 log2(size of cache line in bytes) + * addr register containing start address of region (clobbered) + * asize register containing size of the region in bytes (clobbered) + * askew unique register used as temporary + * + * Note: A possible optimization to this macro is to apply the operation + * to the entire cache if the region exceeds the size of the cache + * by some empirically determined amount or factor. Some experimentation + * is required to determine the appropriate factors, which also need + * to be tunable if required. + */ + + .macro cache_hit_region cainst, linesize_log2, addr, asize, askew + + // Make \asize the number of iterations: + extui \askew, \addr, 0, \linesize_log2 // get unalignment amount of \addr + add \asize, \asize, \askew // ... and add it to \asize + addi \asize, \asize, (1 << \linesize_log2) - 1 // round up! + srli \asize, \asize, \linesize_log2 + + // Iterate over region: + floopnez \asize, cacheh\@ + \cainst \addr, 0 + addi \addr, \addr, (1 << \linesize_log2) // move to next line + floopend \asize, cacheh\@ + + .endm + + + + + +/*************************** INSTRUCTION CACHE ***************************/ + + +/* + * Reset/initialize the instruction cache by simply invalidating it: + * (need to unlock first also, if cache locking implemented): + * + * Parameters: + * aa, ab unique address registers (temporaries) + */ + .macro icache_reset aa, ab, loopokay=0 + icache_unlock_all \aa, \ab, \loopokay + icache_invalidate_all \aa, \ab, \loopokay + .endm + + +/* + * Synchronize after an instruction cache operation, + * to be sure everything is in sync with memory as to be + * expected following any previous instruction cache control operations. + * + * Even if a config doesn't have caches, an isync is still needed + * when instructions in any memory are modified, whether by a loader + * or self-modifying code. Therefore, this macro always produces + * an isync, whether or not an icache is present. + * + * Parameters are: + * ar an address register (temporary) (currently unused, but may be used in future) + */ + .macro icache_sync ar + isync + .endm + + + +/* + * Invalidate a single line of the instruction cache. + * Parameters are: + * ar address register that contains (virtual) address to invalidate + * (may get clobbered in a future implementation, but not currently) + * offset (optional) offset to add to \ar to compute effective address to invalidate + * (note: some number of lsbits are ignored) + */ + .macro icache_invalidate_line ar, offset +#if XCHAL_ICACHE_SIZE > 0 + ihi \ar, \offset // invalidate icache line + /* + * NOTE: in some early version of a test chip silicon (SiChip1), + * 'ihi' didn't work, so software had to replace it with + * the much more draconian 'iii' + * (which would just invalidate more than it should, + * which should be okay other than the performance hit + * because cache locking did not exist in that version, + * unless user somehow relies on something being cached). + * + * #if ... targeting this ancient, now non-existent, test chip silicon ... + * iii \ar, \offset + * #endif + */ + icache_sync \ar +#endif + .endm + + + + +/* + * Invalidate instruction cache entries that cache a specified portion of memory. + * Parameters are: + * astart start address (register gets clobbered) + * asize size of the region in bytes (register gets clobbered) + * ac unique register used as temporary + */ + .macro icache_invalidate_region astart, asize, ac +#if XCHAL_ICACHE_SIZE > 0 + // Instruction cache region invalidation: + cache_hit_region ihi, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac + icache_sync \ac + // End of instruction cache region invalidation +#endif + .endm + + + +/* + * Invalidate entire instruction cache. + * + * Parameters: + * aa, ab unique address registers (temporaries) + */ + .macro icache_invalidate_all aa, ab, loopokay=1 +#if XCHAL_ICACHE_SIZE > 0 + // Instruction cache invalidation: + cache_index_all iii, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, XCHAL_ICACHE_WAYS, \aa, \ab, \loopokay, 1020 + icache_sync \aa + // End of instruction cache invalidation +#endif + .endm + + + +/* + * Lock (prefetch & lock) a single line of the instruction cache. + * + * Parameters are: + * ar address register that contains (virtual) address to lock + * (may get clobbered in a future implementation, but not currently) + * offset offset to add to \ar to compute effective address to lock + * (note: some number of lsbits are ignored) + */ + .macro icache_lock_line ar, offset +#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE + ipfl \ar, \offset /* prefetch and lock icache line */ + icache_sync \ar +#endif + .endm + + + +/* + * Lock (prefetch & lock) a specified portion of memory into the instruction cache. + * Parameters are: + * astart start address (register gets clobbered) + * asize size of the region in bytes (register gets clobbered) + * ac unique register used as temporary + */ + .macro icache_lock_region astart, asize, ac +#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE + // Instruction cache region lock: + cache_hit_region ipfl, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac + icache_sync \ac + // End of instruction cache region lock +#endif + .endm + + + +/* + * Unlock a single line of the instruction cache. + * + * Parameters are: + * ar address register that contains (virtual) address to unlock + * (may get clobbered in a future implementation, but not currently) + * offset offset to add to \ar to compute effective address to unlock + * (note: some number of lsbits are ignored) + */ + .macro icache_unlock_line ar, offset +#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE + ihu \ar, \offset /* unlock icache line */ + icache_sync \ar +#endif + .endm + + + +/* + * Unlock a specified portion of memory from the instruction cache. + * Parameters are: + * astart start address (register gets clobbered) + * asize size of the region in bytes (register gets clobbered) + * ac unique register used as temporary + */ + .macro icache_unlock_region astart, asize, ac +#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE + // Instruction cache region unlock: + cache_hit_region ihu, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac + icache_sync \ac + // End of instruction cache region unlock +#endif + .endm + + + +/* + * Unlock entire instruction cache. + * + * Parameters: + * aa, ab unique address registers (temporaries) + */ + .macro icache_unlock_all aa, ab, loopokay=1 +#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE + // Instruction cache unlock: + cache_index_all iiu, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, 1, \aa, \ab, \loopokay + icache_sync \aa + // End of instruction cache unlock +#endif + .endm + + + + + +/*************************** DATA CACHE ***************************/ + + + +/* + * Reset/initialize the data cache by simply invalidating it + * (need to unlock first also, if cache locking implemented): + * + * Parameters: + * aa, ab unique address registers (temporaries) + */ + .macro dcache_reset aa, ab, loopokay=0 + dcache_unlock_all \aa, \ab, \loopokay + dcache_invalidate_all \aa, \ab, \loopokay + .endm + + + + +/* + * Synchronize after a data cache operation, + * to be sure everything is in sync with memory as to be + * expected following any previous data cache control operations. + * + * Parameters are: + * ar an address register (temporary) (currently unused, but may be used in future) + */ + .macro dcache_sync ar +#if XCHAL_DCACHE_SIZE > 0 + // This previous sequence errs on the conservative side (too much so); a DSYNC should be sufficient: + //memw // synchronize data cache changes relative to subsequent memory accesses + //isync // be conservative and ISYNC as well (just to be sure) + + dsync +#endif + .endm + + + +/* + * Opt into cache coherence. + * + * Parameters are: + * ar,at two scratch address registers (both clobbered) + */ + .macro cache_coherence_on ar at +#if XCHAL_HAVE_EXTERN_REGS && XCHAL_DCACHE_IS_COHERENT + movi \ar, 1 + movi \at, XER_CCON + wer \ar, \at + extw +# endif + .endm + + + +/* + * Opt out of cache coherence. + * NOTE: this is generally preceded by emptying the cache; + * see xthal_cache_coherence_optout() in hal/coherence.c for details. + * + * Parameters are: + * ar,at two scratch address registers (both clobbered) + */ + .macro cache_coherence_off ar at +#if XCHAL_HAVE_EXTERN_REGS && XCHAL_DCACHE_IS_COHERENT + extw + movi \at, 0 + movi \ar, XER_CCON + wer \at, \ar + extw +#endif + .endm + + + +/* + * Synchronize after a data store operation, + * to be sure the stored data is completely off the processor + * (and assuming there is no buffering outside the processor, + * that the data is in memory). This may be required to + * ensure that the processor's write buffers are emptied. + * A MEMW followed by a read guarantees this, by definition. + * We also try to make sure the read itself completes. + * + * Parameters are: + * ar an address register (temporary) + */ + .macro write_sync ar + memw // ensure previous memory accesses are complete prior to subsequent memory accesses + l32i \ar, sp, 0 // completing this read ensures any previous write has completed, because of MEMW + //slot + add \ar, \ar, \ar // use the result of the read to help ensure the read completes (in future architectures) + .endm + + +/* + * Invalidate a single line of the data cache. + * Parameters are: + * ar address register that contains (virtual) address to invalidate + * (may get clobbered in a future implementation, but not currently) + * offset (optional) offset to add to \ar to compute effective address to invalidate + * (note: some number of lsbits are ignored) + */ + .macro dcache_invalidate_line ar, offset +#if XCHAL_DCACHE_SIZE > 0 + dhi \ar, \offset + dcache_sync \ar +#endif + .endm + + + + + +/* + * Invalidate data cache entries that cache a specified portion of memory. + * Parameters are: + * astart start address (register gets clobbered) + * asize size of the region in bytes (register gets clobbered) + * ac unique register used as temporary + */ + .macro dcache_invalidate_region astart, asize, ac +#if XCHAL_DCACHE_SIZE > 0 + // Data cache region invalidation: + cache_hit_region dhi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac + dcache_sync \ac + // End of data cache region invalidation +#endif + .endm + + + +#if 0 +/* + * This is a work-around for a bug in SiChip1. + * To enable the work-around, uncomment this and replace 'dii' + * with 'dii_s1' everywhere, eg. in the dcache_invalidate_all + * macro below. + */ + .macro dii_s1 ar, offset + dii \ar, \offset + or \ar, \ar, \ar + or \ar, \ar, \ar + or \ar, \ar, \ar + or \ar, \ar, \ar + .endm +#endif + + +/* + * Invalidate entire data cache. + * + * Parameters: + * aa, ab unique address registers (temporaries) + */ + .macro dcache_invalidate_all aa, ab, loopokay=1 +#if XCHAL_DCACHE_SIZE > 0 + // Data cache invalidation: + cache_index_all dii, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, XCHAL_DCACHE_WAYS, \aa, \ab, \loopokay, 1020 + dcache_sync \aa + // End of data cache invalidation +#endif + .endm + + + +/* + * Writeback a single line of the data cache. + * Parameters are: + * ar address register that contains (virtual) address to writeback + * (may get clobbered in a future implementation, but not currently) + * offset offset to add to \ar to compute effective address to writeback + * (note: some number of lsbits are ignored) + */ + .macro dcache_writeback_line ar, offset +#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK + dhwb \ar, \offset + dcache_sync \ar +#endif + .endm + + + +/* + * Writeback dirty data cache entries that cache a specified portion of memory. + * Parameters are: + * astart start address (register gets clobbered) + * asize size of the region in bytes (register gets clobbered) + * ac unique register used as temporary + */ + .macro dcache_writeback_region astart, asize, ac +#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK + // Data cache region writeback: + cache_hit_region dhwb, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac + dcache_sync \ac + // End of data cache region writeback +#endif + .endm + + + +/* + * Writeback entire data cache. + * Parameters: + * aa, ab unique address registers (temporaries) + */ + .macro dcache_writeback_all aa, ab, loopokay=1 +#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK + // Data cache writeback: + cache_index_all diwb, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay + dcache_sync \aa + // End of data cache writeback +#endif + .endm + + + +/* + * Writeback and invalidate a single line of the data cache. + * Parameters are: + * ar address register that contains (virtual) address to writeback and invalidate + * (may get clobbered in a future implementation, but not currently) + * offset offset to add to \ar to compute effective address to writeback and invalidate + * (note: some number of lsbits are ignored) + */ + .macro dcache_writeback_inv_line ar, offset +#if XCHAL_DCACHE_SIZE > 0 + dhwbi \ar, \offset /* writeback and invalidate dcache line */ + dcache_sync \ar +#endif + .endm + + + +/* + * Writeback and invalidate data cache entries that cache a specified portion of memory. + * Parameters are: + * astart start address (register gets clobbered) + * asize size of the region in bytes (register gets clobbered) + * ac unique register used as temporary + */ + .macro dcache_writeback_inv_region astart, asize, ac +#if XCHAL_DCACHE_SIZE > 0 + // Data cache region writeback and invalidate: + cache_hit_region dhwbi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac + dcache_sync \ac + // End of data cache region writeback and invalidate +#endif + .endm + + + +/* + * Writeback and invalidate entire data cache. + * Parameters: + * aa, ab unique address registers (temporaries) + */ + .macro dcache_writeback_inv_all aa, ab, loopokay=1 +#if XCHAL_DCACHE_SIZE > 0 + // Data cache writeback and invalidate: +#if XCHAL_DCACHE_IS_WRITEBACK + cache_index_all diwbi, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay + dcache_sync \aa +#else /*writeback*/ + // Data cache does not support writeback, so just invalidate: */ + dcache_invalidate_all \aa, \ab, \loopokay +#endif /*writeback*/ + // End of data cache writeback and invalidate +#endif + .endm + + + + +/* + * Lock (prefetch & lock) a single line of the data cache. + * + * Parameters are: + * ar address register that contains (virtual) address to lock + * (may get clobbered in a future implementation, but not currently) + * offset offset to add to \ar to compute effective address to lock + * (note: some number of lsbits are ignored) + */ + .macro dcache_lock_line ar, offset +#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE + dpfl \ar, \offset /* prefetch and lock dcache line */ + dcache_sync \ar +#endif + .endm + + + +/* + * Lock (prefetch & lock) a specified portion of memory into the data cache. + * Parameters are: + * astart start address (register gets clobbered) + * asize size of the region in bytes (register gets clobbered) + * ac unique register used as temporary + */ + .macro dcache_lock_region astart, asize, ac +#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE + // Data cache region lock: + cache_hit_region dpfl, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac + dcache_sync \ac + // End of data cache region lock +#endif + .endm + + + +/* + * Unlock a single line of the data cache. + * + * Parameters are: + * ar address register that contains (virtual) address to unlock + * (may get clobbered in a future implementation, but not currently) + * offset offset to add to \ar to compute effective address to unlock + * (note: some number of lsbits are ignored) + */ + .macro dcache_unlock_line ar, offset +#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE + dhu \ar, \offset /* unlock dcache line */ + dcache_sync \ar +#endif + .endm + + + +/* + * Unlock a specified portion of memory from the data cache. + * Parameters are: + * astart start address (register gets clobbered) + * asize size of the region in bytes (register gets clobbered) + * ac unique register used as temporary + */ + .macro dcache_unlock_region astart, asize, ac +#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE + // Data cache region unlock: + cache_hit_region dhu, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac + dcache_sync \ac + // End of data cache region unlock +#endif + .endm + + + +/* + * Unlock entire data cache. + * + * Parameters: + * aa, ab unique address registers (temporaries) + */ + .macro dcache_unlock_all aa, ab, loopokay=1 +#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE + // Data cache unlock: + cache_index_all diu, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay + dcache_sync \aa + // End of data cache unlock +#endif + .endm + + +#endif /*XTENSA_CACHEASM_H*/ + diff --git a/extra_include/xtensa/cacheattrasm.h b/extra_include/xtensa/cacheattrasm.h index 6e2f0ab0..20c4cfd5 100644 --- a/extra_include/xtensa/cacheattrasm.h +++ b/extra_include/xtensa/cacheattrasm.h @@ -1,436 +1,436 @@ -/* - * xtensa/cacheattrasm.h -- assembler-specific CACHEATTR register related definitions - * that depend on CORE configuration - * - * This file is logically part of xtensa/coreasm.h (or perhaps xtensa/cacheasm.h), - * but is kept separate for modularity / compilation-performance. - */ - -/* - * Copyright (c) 2001-2009 Tensilica Inc. - * - * 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 XTENSA_CACHEATTRASM_H -#define XTENSA_CACHEATTRASM_H - -#include - -/* Determine whether cache attributes are controlled using eight 512MB entries: */ -#define XCHAL_CA_8X512 (XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR \ - || (XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY)) - - -/* - * This header file defines assembler macros of the form: - * cacheattr_ - * where: - * is 'i', 'd' or absent for instruction, data - * or both caches; and - * indicates the function of the macro. - * - * The following functions are defined: - * - * icacheattr_get - * Reads I-cache CACHEATTR into a2 (clobbers a3-a5). - * - * dcacheattr_get - * Reads D-cache CACHEATTR into a2 (clobbers a3-a5). - * (Note: for configs with a real CACHEATTR register, the - * above two macros are identical.) - * - * cacheattr_set - * Writes both I-cache and D-cache CACHEATTRs from a2 (a3-a8 clobbered). - * Works even when changing one's own code's attributes. - * - * icacheattr_is_enabled label - * Branches to \label if I-cache appears to have been enabled - * (eg. if CACHEATTR contains a cache-enabled attribute). - * (clobbers a2-a5,SAR) - * - * dcacheattr_is_enabled label - * Branches to \label if D-cache appears to have been enabled - * (eg. if CACHEATTR contains a cache-enabled attribute). - * (clobbers a2-a5,SAR) - * - * cacheattr_is_enabled label - * Branches to \label if either I-cache or D-cache appears to have been enabled - * (eg. if CACHEATTR contains a cache-enabled attribute). - * (clobbers a2-a5,SAR) - * - * The following macros are only defined under certain conditions: - * - * icacheattr_set (if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR) - * Writes I-cache CACHEATTR from a2 (a3-a8 clobbered). - * - * dcacheattr_set (if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR) - * Writes D-cache CACHEATTR from a2 (a3-a8 clobbered). - */ - - - -/*************************** GENERIC -- ALL CACHES ***************************/ - -/* - * _cacheattr_get - * - * (Internal macro.) - * Returns value of CACHEATTR register (or closest equivalent) in a2. - * - * Entry: - * (none) - * Exit: - * a2 value read from CACHEATTR - * a3-a5 clobbered (temporaries) - */ - .macro _cacheattr_get tlb -#if XCHAL_HAVE_CACHEATTR - rsr a2, CACHEATTR -#elif XCHAL_CA_8X512 - // We have a config that "mimics" CACHEATTR using a simplified - // "MMU" composed of a single statically-mapped way. - // DTLB and ITLB are independent, so there's no single - // cache attribute that can describe both. So for now - // just return the DTLB state. - movi a5, 0xE0000000 - movi a2, 0 - movi a3, XCHAL_SPANNING_WAY -1: add a3, a3, a5 // next segment - r&tlb&1 a4, a3 // get PPN+CA of segment at 0xE0000000, 0xC0000000, ..., 0 - dsync // interlock??? - slli a2, a2, 4 - extui a4, a4, 0, 4 // extract CA - or a2, a2, a4 - bgeui a3, 16, 1b -#else - // This macro isn't applicable to arbitrary MMU configurations. - // Just return zero. - movi a2, 0 -#endif - .endm - - .macro icacheattr_get - _cacheattr_get itlb - .endm - - .macro dcacheattr_get - _cacheattr_get dtlb - .endm - - -/* Default (powerup/reset) value of CACHEATTR, - all BYPASS mode (ie. disabled/bypassed caches): */ -#if XCHAL_HAVE_PTP_MMU -# define XCHAL_CACHEATTR_ALL_BYPASS 0x33333333 -#else -# define XCHAL_CACHEATTR_ALL_BYPASS 0x22222222 -#endif - -#if XCHAL_CA_8X512 - -#if XCHAL_HAVE_PTP_MMU -# define XCHAL_FCA_ENAMASK 0x0AA0 /* bitmap of fetch attributes that require enabled icache */ -# define XCHAL_LCA_ENAMASK 0x0FF0 /* bitmap of load attributes that require enabled dcache */ -# define XCHAL_SCA_ENAMASK 0x0CC0 /* bitmap of store attributes that require enabled dcache */ -#else -# define XCHAL_FCA_ENAMASK 0x003A /* bitmap of fetch attributes that require enabled icache */ -# define XCHAL_LCA_ENAMASK 0x0033 /* bitmap of load attributes that require enabled dcache */ -# define XCHAL_SCA_ENAMASK 0x0033 /* bitmap of store attributes that require enabled dcache */ -#endif -#define XCHAL_LSCA_ENAMASK (XCHAL_LCA_ENAMASK|XCHAL_SCA_ENAMASK) /* l/s attrs requiring enabled dcache */ -#define XCHAL_ALLCA_ENAMASK (XCHAL_FCA_ENAMASK|XCHAL_LSCA_ENAMASK) /* all attrs requiring enabled caches */ - -/* - * _cacheattr_is_enabled - * - * (Internal macro.) - * Branches to \label if CACHEATTR in a2 indicates an enabled - * cache, using mask in a3. - * - * Parameters: - * label where to branch to if cache is enabled - * Entry: - * a2 contains CACHEATTR value used to determine whether - * caches are enabled - * a3 16-bit constant where each bit correspond to - * one of the 16 possible CA values (in a CACHEATTR mask); - * CA values that indicate the cache is enabled - * have their corresponding bit set in this mask - * (eg. use XCHAL_xCA_ENAMASK , above) - * Exit: - * a2,a4,a5 clobbered - * SAR clobbered - */ - .macro _cacheattr_is_enabled label - movi a4, 8 // loop 8 times -.Lcaife\@: - extui a5, a2, 0, 4 // get CA nibble - ssr a5 // index into mask according to CA... - srl a5, a3 // ...and get CA's mask bit in a5 bit 0 - bbsi.l a5, 0, \label // if CA indicates cache enabled, jump to label - srli a2, a2, 4 // next nibble - addi a4, a4, -1 - bnez a4, .Lcaife\@ // loop for each nibble - .endm - -#else /* XCHAL_CA_8X512 */ - .macro _cacheattr_is_enabled label - j \label // macro not applicable, assume caches always enabled - .endm -#endif /* XCHAL_CA_8X512 */ - - - -/* - * icacheattr_is_enabled - * - * Branches to \label if I-cache is enabled. - * - * Parameters: - * label where to branch to if icache is enabled - * Entry: - * (none) - * Exit: - * a2-a5, SAR clobbered (temporaries) - */ - .macro icacheattr_is_enabled label -#if XCHAL_CA_8X512 - icacheattr_get - movi a3, XCHAL_FCA_ENAMASK -#endif - _cacheattr_is_enabled \label - .endm - -/* - * dcacheattr_is_enabled - * - * Branches to \label if D-cache is enabled. - * - * Parameters: - * label where to branch to if dcache is enabled - * Entry: - * (none) - * Exit: - * a2-a5, SAR clobbered (temporaries) - */ - .macro dcacheattr_is_enabled label -#if XCHAL_CA_8X512 - dcacheattr_get - movi a3, XCHAL_LSCA_ENAMASK -#endif - _cacheattr_is_enabled \label - .endm - -/* - * cacheattr_is_enabled - * - * Branches to \label if either I-cache or D-cache is enabled. - * - * Parameters: - * label where to branch to if a cache is enabled - * Entry: - * (none) - * Exit: - * a2-a5, SAR clobbered (temporaries) - */ - .macro cacheattr_is_enabled label -#if XCHAL_HAVE_CACHEATTR - rsr a2, CACHEATTR - movi a3, XCHAL_ALLCA_ENAMASK -#elif XCHAL_CA_8X512 - icacheattr_get - movi a3, XCHAL_FCA_ENAMASK - _cacheattr_is_enabled \label - dcacheattr_get - movi a3, XCHAL_LSCA_ENAMASK -#endif - _cacheattr_is_enabled \label - .endm - - - -/* - * The ISA does not have a defined way to change the - * instruction cache attributes of the running code, - * ie. of the memory area that encloses the current PC. - * However, each micro-architecture (or class of - * configurations within a micro-architecture) - * provides a way to deal with this issue. - * - * Here are a few macros used to implement the relevant - * approach taken. - */ - -#if XCHAL_CA_8X512 && !XCHAL_HAVE_CACHEATTR - // We have a config that "mimics" CACHEATTR using a simplified - // "MMU" composed of a single statically-mapped way. - -/* - * icacheattr_set - * - * Entry: - * a2 cacheattr value to set - * Exit: - * a2 unchanged - * a3-a8 clobbered (temporaries) - */ - .macro icacheattr_set - - movi a5, 0xE0000000 // mask of upper 3 bits - movi a6, 3f // PC where ITLB is set - movi a3, XCHAL_SPANNING_WAY // start at region 0 (0 .. 7) - mov a7, a2 // copy a2 so it doesn't get clobbered - and a6, a6, a5 // upper 3 bits of local PC area - j 3f - - // Use micro-architecture specific method. - // The following 4-instruction sequence is aligned such that - // it all fits within a single I-cache line. Sixteen byte - // alignment is sufficient for this (using XCHAL_ICACHE_LINESIZE - // actually causes problems because that can be greater than - // the alignment of the reset vector, where this macro is often - // invoked, which would cause the linker to align the reset - // vector code away from the reset vector!!). - .begin no-transform - .align 16 /*XCHAL_ICACHE_LINESIZE*/ -1: witlb a4, a3 // write wired PTE (CA, no PPN) of 512MB segment to ITLB - isync - .end no-transform - nop - nop - - sub a3, a3, a5 // next segment (add 0x20000000) - bltui a3, 16, 4f // done? - - // Note that in the WITLB loop, we don't do any load/stores - // (may not be an issue here, but it is important in the DTLB case). -2: srli a7, a7, 4 // next CA -3: -# if XCHAL_HAVE_MIMIC_CACHEATTR - extui a4, a7, 0, 4 // extract CA to set -# else /* have translation, preserve it: */ - ritlb1 a8, a3 // get current PPN+CA of segment - //dsync // interlock??? - extui a4, a7, 0, 4 // extract CA to set - srli a8, a8, 4 // clear CA but keep PPN ... - slli a8, a8, 4 // ... - add a4, a4, a8 // combine new CA with PPN to preserve -# endif - beq a3, a6, 1b // current PC's region? if so, do it in a safe way - witlb a4, a3 // write wired PTE (CA [+PPN]) of 512MB segment to ITLB - sub a3, a3, a5 // next segment (add 0x20000000) - bgeui a3, 16, 2b - isync // make sure all ifetch changes take effect -4: - .endm // icacheattr_set - - -/* - * dcacheattr_set - * - * Entry: - * a2 cacheattr value to set - * Exit: - * a2 unchanged - * a3-a8 clobbered (temporaries) - */ - - .macro dcacheattr_set - - movi a5, 0xE0000000 // mask of upper 3 bits - movi a3, XCHAL_SPANNING_WAY // start at region 0 (0 .. 7) - mov a7, a2 // copy a2 so it doesn't get clobbered - // Note that in the WDTLB loop, we don't do any load/stores -2: // (including implicit l32r via movi) because it isn't safe. -# if XCHAL_HAVE_MIMIC_CACHEATTR - extui a4, a7, 0, 4 // extract CA to set -# else /* have translation, preserve it: */ - rdtlb1 a8, a3 // get current PPN+CA of segment - //dsync // interlock??? - extui a4, a7, 0, 4 // extract CA to set - srli a8, a8, 4 // clear CA but keep PPN ... - slli a8, a8, 4 // ... - add a4, a4, a8 // combine new CA with PPN to preserve -# endif - wdtlb a4, a3 // write wired PTE (CA [+PPN]) of 512MB segment to DTLB - sub a3, a3, a5 // next segment (add 0x20000000) - srli a7, a7, 4 // next CA - bgeui a3, 16, 2b - dsync // make sure all data path changes take effect - .endm // dcacheattr_set - -#endif /* XCHAL_CA_8X512 && !XCHAL_HAVE_CACHEATTR */ - - - -/* - * cacheattr_set - * - * Macro that sets the current CACHEATTR safely - * (both i and d) according to the current contents of a2. - * It works even when changing the cache attributes of - * the currently running code. - * - * Entry: - * a2 cacheattr value to set - * Exit: - * a2 unchanged - * a3-a8 clobbered (temporaries) - */ - .macro cacheattr_set - -#if XCHAL_HAVE_CACHEATTR -# if XCHAL_ICACHE_LINESIZE < 4 - // No i-cache, so can always safely write to CACHEATTR: - wsr a2, CACHEATTR -# else - // The Athens micro-architecture, when using the old - // exception architecture option (ie. with the CACHEATTR register) - // allows changing the cache attributes of the running code - // using the following exact sequence aligned to be within - // an instruction cache line. (NOTE: using XCHAL_ICACHE_LINESIZE - // alignment actually causes problems because that can be greater - // than the alignment of the reset vector, where this macro is often - // invoked, which would cause the linker to align the reset - // vector code away from the reset vector!!). - j 1f - .begin no-transform - .align 16 /*XCHAL_ICACHE_LINESIZE*/ // align to within an I-cache line -1: wsr a2, CACHEATTR - isync - .end no-transform - nop - nop -# endif -#elif XCHAL_CA_8X512 - // DTLB and ITLB are independent, but to keep semantics - // of this macro we simply write to both. - icacheattr_set - dcacheattr_set -#else - // This macro isn't applicable to arbitrary MMU configurations. - // Do nothing in this case. -#endif - .endm - - -#endif /*XTENSA_CACHEATTRASM_H*/ - +/* + * xtensa/cacheattrasm.h -- assembler-specific CACHEATTR register related definitions + * that depend on CORE configuration + * + * This file is logically part of xtensa/coreasm.h (or perhaps xtensa/cacheasm.h), + * but is kept separate for modularity / compilation-performance. + */ + +/* + * Copyright (c) 2001-2009 Tensilica Inc. + * + * 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 XTENSA_CACHEATTRASM_H +#define XTENSA_CACHEATTRASM_H + +#include + +/* Determine whether cache attributes are controlled using eight 512MB entries: */ +#define XCHAL_CA_8X512 (XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR \ + || (XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY)) + + +/* + * This header file defines assembler macros of the form: + * cacheattr_ + * where: + * is 'i', 'd' or absent for instruction, data + * or both caches; and + * indicates the function of the macro. + * + * The following functions are defined: + * + * icacheattr_get + * Reads I-cache CACHEATTR into a2 (clobbers a3-a5). + * + * dcacheattr_get + * Reads D-cache CACHEATTR into a2 (clobbers a3-a5). + * (Note: for configs with a real CACHEATTR register, the + * above two macros are identical.) + * + * cacheattr_set + * Writes both I-cache and D-cache CACHEATTRs from a2 (a3-a8 clobbered). + * Works even when changing one's own code's attributes. + * + * icacheattr_is_enabled label + * Branches to \label if I-cache appears to have been enabled + * (eg. if CACHEATTR contains a cache-enabled attribute). + * (clobbers a2-a5,SAR) + * + * dcacheattr_is_enabled label + * Branches to \label if D-cache appears to have been enabled + * (eg. if CACHEATTR contains a cache-enabled attribute). + * (clobbers a2-a5,SAR) + * + * cacheattr_is_enabled label + * Branches to \label if either I-cache or D-cache appears to have been enabled + * (eg. if CACHEATTR contains a cache-enabled attribute). + * (clobbers a2-a5,SAR) + * + * The following macros are only defined under certain conditions: + * + * icacheattr_set (if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR) + * Writes I-cache CACHEATTR from a2 (a3-a8 clobbered). + * + * dcacheattr_set (if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR) + * Writes D-cache CACHEATTR from a2 (a3-a8 clobbered). + */ + + + +/*************************** GENERIC -- ALL CACHES ***************************/ + +/* + * _cacheattr_get + * + * (Internal macro.) + * Returns value of CACHEATTR register (or closest equivalent) in a2. + * + * Entry: + * (none) + * Exit: + * a2 value read from CACHEATTR + * a3-a5 clobbered (temporaries) + */ + .macro _cacheattr_get tlb +#if XCHAL_HAVE_CACHEATTR + rsr a2, CACHEATTR +#elif XCHAL_CA_8X512 + // We have a config that "mimics" CACHEATTR using a simplified + // "MMU" composed of a single statically-mapped way. + // DTLB and ITLB are independent, so there's no single + // cache attribute that can describe both. So for now + // just return the DTLB state. + movi a5, 0xE0000000 + movi a2, 0 + movi a3, XCHAL_SPANNING_WAY +1: add a3, a3, a5 // next segment + r&tlb&1 a4, a3 // get PPN+CA of segment at 0xE0000000, 0xC0000000, ..., 0 + dsync // interlock??? + slli a2, a2, 4 + extui a4, a4, 0, 4 // extract CA + or a2, a2, a4 + bgeui a3, 16, 1b +#else + // This macro isn't applicable to arbitrary MMU configurations. + // Just return zero. + movi a2, 0 +#endif + .endm + + .macro icacheattr_get + _cacheattr_get itlb + .endm + + .macro dcacheattr_get + _cacheattr_get dtlb + .endm + + +/* Default (powerup/reset) value of CACHEATTR, + all BYPASS mode (ie. disabled/bypassed caches): */ +#if XCHAL_HAVE_PTP_MMU +# define XCHAL_CACHEATTR_ALL_BYPASS 0x33333333 +#else +# define XCHAL_CACHEATTR_ALL_BYPASS 0x22222222 +#endif + +#if XCHAL_CA_8X512 + +#if XCHAL_HAVE_PTP_MMU +# define XCHAL_FCA_ENAMASK 0x0AA0 /* bitmap of fetch attributes that require enabled icache */ +# define XCHAL_LCA_ENAMASK 0x0FF0 /* bitmap of load attributes that require enabled dcache */ +# define XCHAL_SCA_ENAMASK 0x0CC0 /* bitmap of store attributes that require enabled dcache */ +#else +# define XCHAL_FCA_ENAMASK 0x003A /* bitmap of fetch attributes that require enabled icache */ +# define XCHAL_LCA_ENAMASK 0x0033 /* bitmap of load attributes that require enabled dcache */ +# define XCHAL_SCA_ENAMASK 0x0033 /* bitmap of store attributes that require enabled dcache */ +#endif +#define XCHAL_LSCA_ENAMASK (XCHAL_LCA_ENAMASK|XCHAL_SCA_ENAMASK) /* l/s attrs requiring enabled dcache */ +#define XCHAL_ALLCA_ENAMASK (XCHAL_FCA_ENAMASK|XCHAL_LSCA_ENAMASK) /* all attrs requiring enabled caches */ + +/* + * _cacheattr_is_enabled + * + * (Internal macro.) + * Branches to \label if CACHEATTR in a2 indicates an enabled + * cache, using mask in a3. + * + * Parameters: + * label where to branch to if cache is enabled + * Entry: + * a2 contains CACHEATTR value used to determine whether + * caches are enabled + * a3 16-bit constant where each bit correspond to + * one of the 16 possible CA values (in a CACHEATTR mask); + * CA values that indicate the cache is enabled + * have their corresponding bit set in this mask + * (eg. use XCHAL_xCA_ENAMASK , above) + * Exit: + * a2,a4,a5 clobbered + * SAR clobbered + */ + .macro _cacheattr_is_enabled label + movi a4, 8 // loop 8 times +.Lcaife\@: + extui a5, a2, 0, 4 // get CA nibble + ssr a5 // index into mask according to CA... + srl a5, a3 // ...and get CA's mask bit in a5 bit 0 + bbsi.l a5, 0, \label // if CA indicates cache enabled, jump to label + srli a2, a2, 4 // next nibble + addi a4, a4, -1 + bnez a4, .Lcaife\@ // loop for each nibble + .endm + +#else /* XCHAL_CA_8X512 */ + .macro _cacheattr_is_enabled label + j \label // macro not applicable, assume caches always enabled + .endm +#endif /* XCHAL_CA_8X512 */ + + + +/* + * icacheattr_is_enabled + * + * Branches to \label if I-cache is enabled. + * + * Parameters: + * label where to branch to if icache is enabled + * Entry: + * (none) + * Exit: + * a2-a5, SAR clobbered (temporaries) + */ + .macro icacheattr_is_enabled label +#if XCHAL_CA_8X512 + icacheattr_get + movi a3, XCHAL_FCA_ENAMASK +#endif + _cacheattr_is_enabled \label + .endm + +/* + * dcacheattr_is_enabled + * + * Branches to \label if D-cache is enabled. + * + * Parameters: + * label where to branch to if dcache is enabled + * Entry: + * (none) + * Exit: + * a2-a5, SAR clobbered (temporaries) + */ + .macro dcacheattr_is_enabled label +#if XCHAL_CA_8X512 + dcacheattr_get + movi a3, XCHAL_LSCA_ENAMASK +#endif + _cacheattr_is_enabled \label + .endm + +/* + * cacheattr_is_enabled + * + * Branches to \label if either I-cache or D-cache is enabled. + * + * Parameters: + * label where to branch to if a cache is enabled + * Entry: + * (none) + * Exit: + * a2-a5, SAR clobbered (temporaries) + */ + .macro cacheattr_is_enabled label +#if XCHAL_HAVE_CACHEATTR + rsr a2, CACHEATTR + movi a3, XCHAL_ALLCA_ENAMASK +#elif XCHAL_CA_8X512 + icacheattr_get + movi a3, XCHAL_FCA_ENAMASK + _cacheattr_is_enabled \label + dcacheattr_get + movi a3, XCHAL_LSCA_ENAMASK +#endif + _cacheattr_is_enabled \label + .endm + + + +/* + * The ISA does not have a defined way to change the + * instruction cache attributes of the running code, + * ie. of the memory area that encloses the current PC. + * However, each micro-architecture (or class of + * configurations within a micro-architecture) + * provides a way to deal with this issue. + * + * Here are a few macros used to implement the relevant + * approach taken. + */ + +#if XCHAL_CA_8X512 && !XCHAL_HAVE_CACHEATTR + // We have a config that "mimics" CACHEATTR using a simplified + // "MMU" composed of a single statically-mapped way. + +/* + * icacheattr_set + * + * Entry: + * a2 cacheattr value to set + * Exit: + * a2 unchanged + * a3-a8 clobbered (temporaries) + */ + .macro icacheattr_set + + movi a5, 0xE0000000 // mask of upper 3 bits + movi a6, 3f // PC where ITLB is set + movi a3, XCHAL_SPANNING_WAY // start at region 0 (0 .. 7) + mov a7, a2 // copy a2 so it doesn't get clobbered + and a6, a6, a5 // upper 3 bits of local PC area + j 3f + + // Use micro-architecture specific method. + // The following 4-instruction sequence is aligned such that + // it all fits within a single I-cache line. Sixteen byte + // alignment is sufficient for this (using XCHAL_ICACHE_LINESIZE + // actually causes problems because that can be greater than + // the alignment of the reset vector, where this macro is often + // invoked, which would cause the linker to align the reset + // vector code away from the reset vector!!). + .begin no-transform + .align 16 /*XCHAL_ICACHE_LINESIZE*/ +1: witlb a4, a3 // write wired PTE (CA, no PPN) of 512MB segment to ITLB + isync + .end no-transform + nop + nop + + sub a3, a3, a5 // next segment (add 0x20000000) + bltui a3, 16, 4f // done? + + // Note that in the WITLB loop, we don't do any load/stores + // (may not be an issue here, but it is important in the DTLB case). +2: srli a7, a7, 4 // next CA +3: +# if XCHAL_HAVE_MIMIC_CACHEATTR + extui a4, a7, 0, 4 // extract CA to set +# else /* have translation, preserve it: */ + ritlb1 a8, a3 // get current PPN+CA of segment + //dsync // interlock??? + extui a4, a7, 0, 4 // extract CA to set + srli a8, a8, 4 // clear CA but keep PPN ... + slli a8, a8, 4 // ... + add a4, a4, a8 // combine new CA with PPN to preserve +# endif + beq a3, a6, 1b // current PC's region? if so, do it in a safe way + witlb a4, a3 // write wired PTE (CA [+PPN]) of 512MB segment to ITLB + sub a3, a3, a5 // next segment (add 0x20000000) + bgeui a3, 16, 2b + isync // make sure all ifetch changes take effect +4: + .endm // icacheattr_set + + +/* + * dcacheattr_set + * + * Entry: + * a2 cacheattr value to set + * Exit: + * a2 unchanged + * a3-a8 clobbered (temporaries) + */ + + .macro dcacheattr_set + + movi a5, 0xE0000000 // mask of upper 3 bits + movi a3, XCHAL_SPANNING_WAY // start at region 0 (0 .. 7) + mov a7, a2 // copy a2 so it doesn't get clobbered + // Note that in the WDTLB loop, we don't do any load/stores +2: // (including implicit l32r via movi) because it isn't safe. +# if XCHAL_HAVE_MIMIC_CACHEATTR + extui a4, a7, 0, 4 // extract CA to set +# else /* have translation, preserve it: */ + rdtlb1 a8, a3 // get current PPN+CA of segment + //dsync // interlock??? + extui a4, a7, 0, 4 // extract CA to set + srli a8, a8, 4 // clear CA but keep PPN ... + slli a8, a8, 4 // ... + add a4, a4, a8 // combine new CA with PPN to preserve +# endif + wdtlb a4, a3 // write wired PTE (CA [+PPN]) of 512MB segment to DTLB + sub a3, a3, a5 // next segment (add 0x20000000) + srli a7, a7, 4 // next CA + bgeui a3, 16, 2b + dsync // make sure all data path changes take effect + .endm // dcacheattr_set + +#endif /* XCHAL_CA_8X512 && !XCHAL_HAVE_CACHEATTR */ + + + +/* + * cacheattr_set + * + * Macro that sets the current CACHEATTR safely + * (both i and d) according to the current contents of a2. + * It works even when changing the cache attributes of + * the currently running code. + * + * Entry: + * a2 cacheattr value to set + * Exit: + * a2 unchanged + * a3-a8 clobbered (temporaries) + */ + .macro cacheattr_set + +#if XCHAL_HAVE_CACHEATTR +# if XCHAL_ICACHE_LINESIZE < 4 + // No i-cache, so can always safely write to CACHEATTR: + wsr a2, CACHEATTR +# else + // The Athens micro-architecture, when using the old + // exception architecture option (ie. with the CACHEATTR register) + // allows changing the cache attributes of the running code + // using the following exact sequence aligned to be within + // an instruction cache line. (NOTE: using XCHAL_ICACHE_LINESIZE + // alignment actually causes problems because that can be greater + // than the alignment of the reset vector, where this macro is often + // invoked, which would cause the linker to align the reset + // vector code away from the reset vector!!). + j 1f + .begin no-transform + .align 16 /*XCHAL_ICACHE_LINESIZE*/ // align to within an I-cache line +1: wsr a2, CACHEATTR + isync + .end no-transform + nop + nop +# endif +#elif XCHAL_CA_8X512 + // DTLB and ITLB are independent, but to keep semantics + // of this macro we simply write to both. + icacheattr_set + dcacheattr_set +#else + // This macro isn't applicable to arbitrary MMU configurations. + // Do nothing in this case. +#endif + .endm + + +#endif /*XTENSA_CACHEATTRASM_H*/ + diff --git a/extra_include/xtensa/config/core-isa.h b/extra_include/xtensa/config/core-isa.h index a1045a20..1128a0c7 100644 --- a/extra_include/xtensa/config/core-isa.h +++ b/extra_include/xtensa/config/core-isa.h @@ -1,459 +1,459 @@ -/* - * xtensa/config/core-isa.h -- HAL definitions that are dependent on Xtensa - * processor CORE configuration - * - * See , which includes this file, for more details. - */ - -/* Xtensa processor core configuration information. - - Customer ID=7011; Build=0x2b6f6; Copyright (c) 1999-2010 Tensilica Inc. - - 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 _XTENSA_CORE_CONFIGURATION_H -#define _XTENSA_CORE_CONFIGURATION_H - - -/**************************************************************************** - Parameters Useful for Any Code, USER or PRIVILEGED - ****************************************************************************/ - -/* - * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is - * configured, and a value of 0 otherwise. These macros are always defined. - */ - - -/*---------------------------------------------------------------------- - ISA - ----------------------------------------------------------------------*/ - -#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */ -#define XCHAL_HAVE_WINDOWED 0 /* windowed registers option */ -#define XCHAL_NUM_AREGS 16 /* num of physical addr regs */ -#define XCHAL_NUM_AREGS_LOG2 4 /* log2(XCHAL_NUM_AREGS) */ -#define XCHAL_MAX_INSTRUCTION_SIZE 3 /* max instr bytes (3..8) */ -#define XCHAL_HAVE_DEBUG 1 /* debug option */ -#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */ -#define XCHAL_HAVE_LOOPS 0 /* zero-overhead loops */ -#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */ -#define XCHAL_HAVE_MINMAX 0 /* MIN/MAX instructions */ -#define XCHAL_HAVE_SEXT 0 /* SEXT instruction */ -#define XCHAL_HAVE_CLAMPS 0 /* CLAMPS instruction */ -#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */ -#define XCHAL_HAVE_MUL32 1 /* MULL instruction */ -#define XCHAL_HAVE_MUL32_HIGH 0 /* MULUH/MULSH instructions */ -#define XCHAL_HAVE_DIV32 0 /* QUOS/QUOU/REMS/REMU instructions */ -#define XCHAL_HAVE_L32R 1 /* L32R instruction */ -#define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */ -#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */ -#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */ -#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */ -#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */ -#define XCHAL_HAVE_CALL4AND12 0 /* (obsolete option) */ -#define XCHAL_HAVE_ABS 1 /* ABS instruction */ -/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */ -/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */ -#define XCHAL_HAVE_RELEASE_SYNC 0 /* L32AI/S32RI instructions */ -#define XCHAL_HAVE_S32C1I 0 /* S32C1I instruction */ -#define XCHAL_HAVE_SPECULATION 0 /* speculation */ -#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */ -#define XCHAL_NUM_CONTEXTS 1 /* */ -#define XCHAL_NUM_MISC_REGS 0 /* num of scratch regs (0..4) */ -#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */ -#define XCHAL_HAVE_PRID 1 /* processor ID register */ -#define XCHAL_HAVE_EXTERN_REGS 1 /* WER/RER instructions */ -#define XCHAL_HAVE_MP_INTERRUPTS 0 /* interrupt distributor port */ -#define XCHAL_HAVE_MP_RUNSTALL 0 /* core RunStall control port */ -#define XCHAL_HAVE_THREADPTR 0 /* THREADPTR register */ -#define XCHAL_HAVE_BOOLEANS 0 /* boolean registers */ -#define XCHAL_HAVE_CP 0 /* CPENABLE reg (coprocessor) */ -#define XCHAL_CP_MAXCFG 0 /* max allowed cp id plus one */ -#define XCHAL_HAVE_MAC16 0 /* MAC16 package */ -#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */ -#define XCHAL_HAVE_FP 0 /* floating point pkg */ -#define XCHAL_HAVE_DFP 0 /* double precision FP pkg */ -#define XCHAL_HAVE_DFP_accel 0 /* double precision FP acceleration pkg */ -#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */ -#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */ -#define XCHAL_HAVE_HIFIPRO 0 /* HiFiPro Audio Engine pkg */ -#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */ -#define XCHAL_HAVE_CONNXD2 0 /* ConnX D2 pkg */ - - -/*---------------------------------------------------------------------- - MISC - ----------------------------------------------------------------------*/ - -#define XCHAL_NUM_WRITEBUFFER_ENTRIES 1 /* size of write buffer */ -#define XCHAL_INST_FETCH_WIDTH 4 /* instr-fetch width in bytes */ -#define XCHAL_DATA_WIDTH 4 /* data width in bytes */ -/* In T1050, applies to selected core load and store instructions (see ISA): */ -#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */ -#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/ -#define XCHAL_UNALIGNED_LOAD_HW 0 /* unaligned loads work in hw */ -#define XCHAL_UNALIGNED_STORE_HW 0 /* unaligned stores work in hw*/ - -#define XCHAL_SW_VERSION 800001 /* sw version of this header */ - -#define XCHAL_CORE_ID "lx106" /* alphanum core name - (CoreID) set in the Xtensa - Processor Generator */ - -#define XCHAL_BUILD_UNIQUE_ID 0x0002B6F6 /* 22-bit sw build ID */ - -/* - * These definitions describe the hardware targeted by this software. - */ -#define XCHAL_HW_CONFIGID0 0xC28CDAFA /* ConfigID hi 32 bits*/ -#define XCHAL_HW_CONFIGID1 0x1082B6F6 /* ConfigID lo 32 bits*/ -#define XCHAL_HW_VERSION_NAME "LX3.0.1" /* full version name */ -#define XCHAL_HW_VERSION_MAJOR 2300 /* major ver# of targeted hw */ -#define XCHAL_HW_VERSION_MINOR 1 /* minor ver# of targeted hw */ -#define XCHAL_HW_VERSION 230001 /* major*100+minor */ -#define XCHAL_HW_REL_LX3 1 -#define XCHAL_HW_REL_LX3_0 1 -#define XCHAL_HW_REL_LX3_0_1 1 -#define XCHAL_HW_CONFIGID_RELIABLE 1 -/* If software targets a *range* of hardware versions, these are the bounds: */ -#define XCHAL_HW_MIN_VERSION_MAJOR 2300 /* major v of earliest tgt hw */ -#define XCHAL_HW_MIN_VERSION_MINOR 1 /* minor v of earliest tgt hw */ -#define XCHAL_HW_MIN_VERSION 230001 /* earliest targeted hw */ -#define XCHAL_HW_MAX_VERSION_MAJOR 2300 /* major v of latest tgt hw */ -#define XCHAL_HW_MAX_VERSION_MINOR 1 /* minor v of latest tgt hw */ -#define XCHAL_HW_MAX_VERSION 230001 /* latest targeted hw */ - - -/*---------------------------------------------------------------------- - CACHE - ----------------------------------------------------------------------*/ - -#define XCHAL_ICACHE_LINESIZE 4 /* I-cache line size in bytes */ -#define XCHAL_DCACHE_LINESIZE 4 /* D-cache line size in bytes */ -#define XCHAL_ICACHE_LINEWIDTH 2 /* log2(I line size in bytes) */ -#define XCHAL_DCACHE_LINEWIDTH 2 /* log2(D line size in bytes) */ - -#define XCHAL_ICACHE_SIZE 0 /* I-cache size in bytes or 0 */ -#define XCHAL_DCACHE_SIZE 0 /* D-cache size in bytes or 0 */ - -#define XCHAL_DCACHE_IS_WRITEBACK 0 /* writeback feature */ -#define XCHAL_DCACHE_IS_COHERENT 0 /* MP coherence feature */ - -#define XCHAL_HAVE_PREFETCH 0 /* PREFCTL register */ - - - - -/**************************************************************************** - Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code - ****************************************************************************/ - - -#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY - -/*---------------------------------------------------------------------- - CACHE - ----------------------------------------------------------------------*/ - -#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */ - -/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */ - -/* Number of cache sets in log2(lines per way): */ -#define XCHAL_ICACHE_SETWIDTH 0 -#define XCHAL_DCACHE_SETWIDTH 0 - -/* Cache set associativity (number of ways): */ -#define XCHAL_ICACHE_WAYS 1 -#define XCHAL_DCACHE_WAYS 1 - -/* Cache features: */ -#define XCHAL_ICACHE_LINE_LOCKABLE 0 -#define XCHAL_DCACHE_LINE_LOCKABLE 0 -#define XCHAL_ICACHE_ECC_PARITY 0 -#define XCHAL_DCACHE_ECC_PARITY 0 - -/* Cache access size in bytes (affects operation of SICW instruction): */ -#define XCHAL_ICACHE_ACCESS_SIZE 1 -#define XCHAL_DCACHE_ACCESS_SIZE 1 - -/* Number of encoded cache attr bits (see for decoded bits): */ -#define XCHAL_CA_BITS 4 - - -/*---------------------------------------------------------------------- - INTERNAL I/D RAM/ROMs and XLMI - ----------------------------------------------------------------------*/ - -#define XCHAL_NUM_INSTROM 1 /* number of core instr. ROMs */ -#define XCHAL_NUM_INSTRAM 2 /* number of core instr. RAMs */ -#define XCHAL_NUM_DATAROM 1 /* number of core data ROMs */ -#define XCHAL_NUM_DATARAM 2 /* number of core data RAMs */ -#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/ -#define XCHAL_NUM_XLMI 1 /* number of core XLMI ports */ - -/* Instruction ROM 0: */ -#define XCHAL_INSTROM0_VADDR 0x40200000 -#define XCHAL_INSTROM0_PADDR 0x40200000 -#define XCHAL_INSTROM0_SIZE 1048576 -#define XCHAL_INSTROM0_ECC_PARITY 0 - -/* Instruction RAM 0: */ -#define XCHAL_INSTRAM0_VADDR 0x40000000 -#define XCHAL_INSTRAM0_PADDR 0x40000000 -#define XCHAL_INSTRAM0_SIZE 1048576 -#define XCHAL_INSTRAM0_ECC_PARITY 0 - -/* Instruction RAM 1: */ -#define XCHAL_INSTRAM1_VADDR 0x40100000 -#define XCHAL_INSTRAM1_PADDR 0x40100000 -#define XCHAL_INSTRAM1_SIZE 1048576 -#define XCHAL_INSTRAM1_ECC_PARITY 0 - -/* Data ROM 0: */ -#define XCHAL_DATAROM0_VADDR 0x3FF40000 -#define XCHAL_DATAROM0_PADDR 0x3FF40000 -#define XCHAL_DATAROM0_SIZE 262144 -#define XCHAL_DATAROM0_ECC_PARITY 0 - -/* Data RAM 0: */ -#define XCHAL_DATARAM0_VADDR 0x3FFC0000 -#define XCHAL_DATARAM0_PADDR 0x3FFC0000 -#define XCHAL_DATARAM0_SIZE 262144 -#define XCHAL_DATARAM0_ECC_PARITY 0 - -/* Data RAM 1: */ -#define XCHAL_DATARAM1_VADDR 0x3FF80000 -#define XCHAL_DATARAM1_PADDR 0x3FF80000 -#define XCHAL_DATARAM1_SIZE 262144 -#define XCHAL_DATARAM1_ECC_PARITY 0 - -/* XLMI Port 0: */ -#define XCHAL_XLMI0_VADDR 0x3FF00000 -#define XCHAL_XLMI0_PADDR 0x3FF00000 -#define XCHAL_XLMI0_SIZE 262144 -#define XCHAL_XLMI0_ECC_PARITY 0 - - -/*---------------------------------------------------------------------- - INTERRUPTS and TIMERS - ----------------------------------------------------------------------*/ - -#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */ -#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ -#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */ -#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */ -#define XCHAL_NUM_TIMERS 1 /* number of CCOMPAREn regs */ -#define XCHAL_NUM_INTERRUPTS 15 /* number of interrupts */ -#define XCHAL_NUM_INTERRUPTS_LOG2 4 /* ceil(log2(NUM_INTERRUPTS)) */ -#define XCHAL_NUM_EXTINTERRUPTS 13 /* num of external interrupts */ -#define XCHAL_NUM_INTLEVELS 2 /* number of interrupt levels - (not including level zero) */ -#define XCHAL_EXCM_LEVEL 1 /* level masked by PS.EXCM */ - /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */ - -/* Masks of interrupts at each interrupt level: */ -#define XCHAL_INTLEVEL1_MASK 0x00003FFF -#define XCHAL_INTLEVEL2_MASK 0x00000000 -#define XCHAL_INTLEVEL3_MASK 0x00004000 -#define XCHAL_INTLEVEL4_MASK 0x00000000 -#define XCHAL_INTLEVEL5_MASK 0x00000000 -#define XCHAL_INTLEVEL6_MASK 0x00000000 -#define XCHAL_INTLEVEL7_MASK 0x00000000 - -/* Masks of interrupts at each range 1..n of interrupt levels: */ -#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x00003FFF -#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x00003FFF -#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x00007FFF -#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x00007FFF -#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x00007FFF -#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x00007FFF -#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x00007FFF - -/* Level of each interrupt: */ -#define XCHAL_INT0_LEVEL 1 -#define XCHAL_INT1_LEVEL 1 -#define XCHAL_INT2_LEVEL 1 -#define XCHAL_INT3_LEVEL 1 -#define XCHAL_INT4_LEVEL 1 -#define XCHAL_INT5_LEVEL 1 -#define XCHAL_INT6_LEVEL 1 -#define XCHAL_INT7_LEVEL 1 -#define XCHAL_INT8_LEVEL 1 -#define XCHAL_INT9_LEVEL 1 -#define XCHAL_INT10_LEVEL 1 -#define XCHAL_INT11_LEVEL 1 -#define XCHAL_INT12_LEVEL 1 -#define XCHAL_INT13_LEVEL 1 -#define XCHAL_INT14_LEVEL 3 -#define XCHAL_DEBUGLEVEL 2 /* debug interrupt level */ -#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ -#define XCHAL_NMILEVEL 3 /* NMI "level" (for use with - EXCSAVE/EPS/EPC_n, RFI n) */ - -/* Type of each interrupt: */ -#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL -#define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER -#define XCHAL_INT7_TYPE XTHAL_INTTYPE_SOFTWARE -#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_EDGE -#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_EDGE -#define XCHAL_INT10_TYPE XTHAL_INTTYPE_EXTERN_EDGE -#define XCHAL_INT11_TYPE XTHAL_INTTYPE_EXTERN_EDGE -#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_EDGE -#define XCHAL_INT13_TYPE XTHAL_INTTYPE_EXTERN_EDGE -#define XCHAL_INT14_TYPE XTHAL_INTTYPE_NMI - -/* Masks of interrupts for each type of interrupt: */ -#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFFF8000 -#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000080 -#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00003F00 -#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000003F -#define XCHAL_INTTYPE_MASK_TIMER 0x00000040 -#define XCHAL_INTTYPE_MASK_NMI 0x00004000 -#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000 - -/* Interrupt numbers assigned to specific interrupt sources: */ -#define XCHAL_TIMER0_INTERRUPT 6 /* CCOMPARE0 */ -#define XCHAL_TIMER1_INTERRUPT XTHAL_TIMER_UNCONFIGURED -#define XCHAL_TIMER2_INTERRUPT XTHAL_TIMER_UNCONFIGURED -#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED -#define XCHAL_NMI_INTERRUPT 14 /* non-maskable interrupt */ - -/* Interrupt numbers for levels at which only one interrupt is configured: */ -#define XCHAL_INTLEVEL3_NUM 14 -/* (There are many interrupts each at level(s) 1.) */ - - -/* - * External interrupt vectors/levels. - * These macros describe how Xtensa processor interrupt numbers - * (as numbered internally, eg. in INTERRUPT and INTENABLE registers) - * map to external BInterrupt pins, for those interrupts - * configured as external (level-triggered, edge-triggered, or NMI). - * See the Xtensa processor databook for more details. - */ - -/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */ -#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */ -#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */ -#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */ -#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */ -#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */ -#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */ -#define XCHAL_EXTINT6_NUM 8 /* (intlevel 1) */ -#define XCHAL_EXTINT7_NUM 9 /* (intlevel 1) */ -#define XCHAL_EXTINT8_NUM 10 /* (intlevel 1) */ -#define XCHAL_EXTINT9_NUM 11 /* (intlevel 1) */ -#define XCHAL_EXTINT10_NUM 12 /* (intlevel 1) */ -#define XCHAL_EXTINT11_NUM 13 /* (intlevel 1) */ -#define XCHAL_EXTINT12_NUM 14 /* (intlevel 3) */ - - -/*---------------------------------------------------------------------- - EXCEPTIONS and VECTORS - ----------------------------------------------------------------------*/ - -#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture - number: 1 == XEA1 (old) - 2 == XEA2 (new) - 0 == XEAX (extern) */ -#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */ -#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */ -#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */ -#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */ -#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */ -#define XCHAL_HAVE_VECTOR_SELECT 1 /* relocatable vectors */ -#define XCHAL_HAVE_VECBASE 1 /* relocatable vectors */ -#define XCHAL_VECBASE_RESET_VADDR 0x40000000 /* VECBASE reset value */ -#define XCHAL_VECBASE_RESET_PADDR 0x40000000 -#define XCHAL_RESET_VECBASE_OVERLAP 0 - -#define XCHAL_RESET_VECTOR0_VADDR 0x50000000 -#define XCHAL_RESET_VECTOR0_PADDR 0x50000000 -#define XCHAL_RESET_VECTOR1_VADDR 0x40000080 -#define XCHAL_RESET_VECTOR1_PADDR 0x40000080 -#define XCHAL_RESET_VECTOR_VADDR 0x50000000 -#define XCHAL_RESET_VECTOR_PADDR 0x50000000 -#define XCHAL_USER_VECOFS 0x00000050 -#define XCHAL_USER_VECTOR_VADDR 0x40000050 -#define XCHAL_USER_VECTOR_PADDR 0x40000050 -#define XCHAL_KERNEL_VECOFS 0x00000030 -#define XCHAL_KERNEL_VECTOR_VADDR 0x40000030 -#define XCHAL_KERNEL_VECTOR_PADDR 0x40000030 -#define XCHAL_DOUBLEEXC_VECOFS 0x00000070 -#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x40000070 -#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x40000070 -#define XCHAL_INTLEVEL2_VECOFS 0x00000010 -#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x40000010 -#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x40000010 -#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL2_VECOFS -#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL2_VECTOR_VADDR -#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL2_VECTOR_PADDR -#define XCHAL_NMI_VECOFS 0x00000020 -#define XCHAL_NMI_VECTOR_VADDR 0x40000020 -#define XCHAL_NMI_VECTOR_PADDR 0x40000020 -#define XCHAL_INTLEVEL3_VECOFS XCHAL_NMI_VECOFS -#define XCHAL_INTLEVEL3_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR -#define XCHAL_INTLEVEL3_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR - - -/*---------------------------------------------------------------------- - DEBUG - ----------------------------------------------------------------------*/ - -#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */ -#define XCHAL_NUM_IBREAK 1 /* number of IBREAKn regs */ -#define XCHAL_NUM_DBREAK 1 /* number of DBREAKn regs */ -#define XCHAL_HAVE_OCD_DIR_ARRAY 0 /* faster OCD option */ - - -/*---------------------------------------------------------------------- - MMU - ----------------------------------------------------------------------*/ - -/* See core-matmap.h header file for more details. */ - -#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */ -#define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */ -#define XCHAL_SPANNING_WAY 0 /* TLB spanning way number */ -#define XCHAL_HAVE_IDENTITY_MAP 1 /* vaddr == paddr always */ -#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */ -#define XCHAL_HAVE_MIMIC_CACHEATTR 1 /* region protection */ -#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */ -#define XCHAL_HAVE_PTP_MMU 0 /* full MMU (with page table - [autorefill] and protection) - usable for an MMU-based OS */ -/* If none of the above last 4 are set, it's a custom TLB configuration. */ - -#define XCHAL_MMU_ASID_BITS 0 /* number of bits in ASIDs */ -#define XCHAL_MMU_RINGS 1 /* number of rings (1..4) */ -#define XCHAL_MMU_RING_BITS 0 /* num of bits in RING field */ - -#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ - - -#endif /* _XTENSA_CORE_CONFIGURATION_H */ - +/* + * xtensa/config/core-isa.h -- HAL definitions that are dependent on Xtensa + * processor CORE configuration + * + * See , which includes this file, for more details. + */ + +/* Xtensa processor core configuration information. + + Customer ID=7011; Build=0x2b6f6; Copyright (c) 1999-2010 Tensilica Inc. + + 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 _XTENSA_CORE_CONFIGURATION_H +#define _XTENSA_CORE_CONFIGURATION_H + + +/**************************************************************************** + Parameters Useful for Any Code, USER or PRIVILEGED + ****************************************************************************/ + +/* + * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is + * configured, and a value of 0 otherwise. These macros are always defined. + */ + + +/*---------------------------------------------------------------------- + ISA + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */ +#define XCHAL_HAVE_WINDOWED 0 /* windowed registers option */ +#define XCHAL_NUM_AREGS 16 /* num of physical addr regs */ +#define XCHAL_NUM_AREGS_LOG2 4 /* log2(XCHAL_NUM_AREGS) */ +#define XCHAL_MAX_INSTRUCTION_SIZE 3 /* max instr bytes (3..8) */ +#define XCHAL_HAVE_DEBUG 1 /* debug option */ +#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */ +#define XCHAL_HAVE_LOOPS 0 /* zero-overhead loops */ +#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */ +#define XCHAL_HAVE_MINMAX 0 /* MIN/MAX instructions */ +#define XCHAL_HAVE_SEXT 0 /* SEXT instruction */ +#define XCHAL_HAVE_CLAMPS 0 /* CLAMPS instruction */ +#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */ +#define XCHAL_HAVE_MUL32 1 /* MULL instruction */ +#define XCHAL_HAVE_MUL32_HIGH 0 /* MULUH/MULSH instructions */ +#define XCHAL_HAVE_DIV32 0 /* QUOS/QUOU/REMS/REMU instructions */ +#define XCHAL_HAVE_L32R 1 /* L32R instruction */ +#define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */ +#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */ +#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */ +#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */ +#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */ +#define XCHAL_HAVE_CALL4AND12 0 /* (obsolete option) */ +#define XCHAL_HAVE_ABS 1 /* ABS instruction */ +/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */ +/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */ +#define XCHAL_HAVE_RELEASE_SYNC 0 /* L32AI/S32RI instructions */ +#define XCHAL_HAVE_S32C1I 0 /* S32C1I instruction */ +#define XCHAL_HAVE_SPECULATION 0 /* speculation */ +#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */ +#define XCHAL_NUM_CONTEXTS 1 /* */ +#define XCHAL_NUM_MISC_REGS 0 /* num of scratch regs (0..4) */ +#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */ +#define XCHAL_HAVE_PRID 1 /* processor ID register */ +#define XCHAL_HAVE_EXTERN_REGS 1 /* WER/RER instructions */ +#define XCHAL_HAVE_MP_INTERRUPTS 0 /* interrupt distributor port */ +#define XCHAL_HAVE_MP_RUNSTALL 0 /* core RunStall control port */ +#define XCHAL_HAVE_THREADPTR 0 /* THREADPTR register */ +#define XCHAL_HAVE_BOOLEANS 0 /* boolean registers */ +#define XCHAL_HAVE_CP 0 /* CPENABLE reg (coprocessor) */ +#define XCHAL_CP_MAXCFG 0 /* max allowed cp id plus one */ +#define XCHAL_HAVE_MAC16 0 /* MAC16 package */ +#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */ +#define XCHAL_HAVE_FP 0 /* floating point pkg */ +#define XCHAL_HAVE_DFP 0 /* double precision FP pkg */ +#define XCHAL_HAVE_DFP_accel 0 /* double precision FP acceleration pkg */ +#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */ +#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */ +#define XCHAL_HAVE_HIFIPRO 0 /* HiFiPro Audio Engine pkg */ +#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */ +#define XCHAL_HAVE_CONNXD2 0 /* ConnX D2 pkg */ + + +/*---------------------------------------------------------------------- + MISC + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_WRITEBUFFER_ENTRIES 1 /* size of write buffer */ +#define XCHAL_INST_FETCH_WIDTH 4 /* instr-fetch width in bytes */ +#define XCHAL_DATA_WIDTH 4 /* data width in bytes */ +/* In T1050, applies to selected core load and store instructions (see ISA): */ +#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */ +#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/ +#define XCHAL_UNALIGNED_LOAD_HW 0 /* unaligned loads work in hw */ +#define XCHAL_UNALIGNED_STORE_HW 0 /* unaligned stores work in hw*/ + +#define XCHAL_SW_VERSION 800001 /* sw version of this header */ + +#define XCHAL_CORE_ID "lx106" /* alphanum core name + (CoreID) set in the Xtensa + Processor Generator */ + +#define XCHAL_BUILD_UNIQUE_ID 0x0002B6F6 /* 22-bit sw build ID */ + +/* + * These definitions describe the hardware targeted by this software. + */ +#define XCHAL_HW_CONFIGID0 0xC28CDAFA /* ConfigID hi 32 bits*/ +#define XCHAL_HW_CONFIGID1 0x1082B6F6 /* ConfigID lo 32 bits*/ +#define XCHAL_HW_VERSION_NAME "LX3.0.1" /* full version name */ +#define XCHAL_HW_VERSION_MAJOR 2300 /* major ver# of targeted hw */ +#define XCHAL_HW_VERSION_MINOR 1 /* minor ver# of targeted hw */ +#define XCHAL_HW_VERSION 230001 /* major*100+minor */ +#define XCHAL_HW_REL_LX3 1 +#define XCHAL_HW_REL_LX3_0 1 +#define XCHAL_HW_REL_LX3_0_1 1 +#define XCHAL_HW_CONFIGID_RELIABLE 1 +/* If software targets a *range* of hardware versions, these are the bounds: */ +#define XCHAL_HW_MIN_VERSION_MAJOR 2300 /* major v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION_MINOR 1 /* minor v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION 230001 /* earliest targeted hw */ +#define XCHAL_HW_MAX_VERSION_MAJOR 2300 /* major v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MINOR 1 /* minor v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION 230001 /* latest targeted hw */ + + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_ICACHE_LINESIZE 4 /* I-cache line size in bytes */ +#define XCHAL_DCACHE_LINESIZE 4 /* D-cache line size in bytes */ +#define XCHAL_ICACHE_LINEWIDTH 2 /* log2(I line size in bytes) */ +#define XCHAL_DCACHE_LINEWIDTH 2 /* log2(D line size in bytes) */ + +#define XCHAL_ICACHE_SIZE 0 /* I-cache size in bytes or 0 */ +#define XCHAL_DCACHE_SIZE 0 /* D-cache size in bytes or 0 */ + +#define XCHAL_DCACHE_IS_WRITEBACK 0 /* writeback feature */ +#define XCHAL_DCACHE_IS_COHERENT 0 /* MP coherence feature */ + +#define XCHAL_HAVE_PREFETCH 0 /* PREFCTL register */ + + + + +/**************************************************************************** + Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code + ****************************************************************************/ + + +#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */ + +/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */ + +/* Number of cache sets in log2(lines per way): */ +#define XCHAL_ICACHE_SETWIDTH 0 +#define XCHAL_DCACHE_SETWIDTH 0 + +/* Cache set associativity (number of ways): */ +#define XCHAL_ICACHE_WAYS 1 +#define XCHAL_DCACHE_WAYS 1 + +/* Cache features: */ +#define XCHAL_ICACHE_LINE_LOCKABLE 0 +#define XCHAL_DCACHE_LINE_LOCKABLE 0 +#define XCHAL_ICACHE_ECC_PARITY 0 +#define XCHAL_DCACHE_ECC_PARITY 0 + +/* Cache access size in bytes (affects operation of SICW instruction): */ +#define XCHAL_ICACHE_ACCESS_SIZE 1 +#define XCHAL_DCACHE_ACCESS_SIZE 1 + +/* Number of encoded cache attr bits (see for decoded bits): */ +#define XCHAL_CA_BITS 4 + + +/*---------------------------------------------------------------------- + INTERNAL I/D RAM/ROMs and XLMI + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_INSTROM 1 /* number of core instr. ROMs */ +#define XCHAL_NUM_INSTRAM 2 /* number of core instr. RAMs */ +#define XCHAL_NUM_DATAROM 1 /* number of core data ROMs */ +#define XCHAL_NUM_DATARAM 2 /* number of core data RAMs */ +#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/ +#define XCHAL_NUM_XLMI 1 /* number of core XLMI ports */ + +/* Instruction ROM 0: */ +#define XCHAL_INSTROM0_VADDR 0x40200000 +#define XCHAL_INSTROM0_PADDR 0x40200000 +#define XCHAL_INSTROM0_SIZE 1048576 +#define XCHAL_INSTROM0_ECC_PARITY 0 + +/* Instruction RAM 0: */ +#define XCHAL_INSTRAM0_VADDR 0x40000000 +#define XCHAL_INSTRAM0_PADDR 0x40000000 +#define XCHAL_INSTRAM0_SIZE 1048576 +#define XCHAL_INSTRAM0_ECC_PARITY 0 + +/* Instruction RAM 1: */ +#define XCHAL_INSTRAM1_VADDR 0x40100000 +#define XCHAL_INSTRAM1_PADDR 0x40100000 +#define XCHAL_INSTRAM1_SIZE 1048576 +#define XCHAL_INSTRAM1_ECC_PARITY 0 + +/* Data ROM 0: */ +#define XCHAL_DATAROM0_VADDR 0x3FF40000 +#define XCHAL_DATAROM0_PADDR 0x3FF40000 +#define XCHAL_DATAROM0_SIZE 262144 +#define XCHAL_DATAROM0_ECC_PARITY 0 + +/* Data RAM 0: */ +#define XCHAL_DATARAM0_VADDR 0x3FFC0000 +#define XCHAL_DATARAM0_PADDR 0x3FFC0000 +#define XCHAL_DATARAM0_SIZE 262144 +#define XCHAL_DATARAM0_ECC_PARITY 0 + +/* Data RAM 1: */ +#define XCHAL_DATARAM1_VADDR 0x3FF80000 +#define XCHAL_DATARAM1_PADDR 0x3FF80000 +#define XCHAL_DATARAM1_SIZE 262144 +#define XCHAL_DATARAM1_ECC_PARITY 0 + +/* XLMI Port 0: */ +#define XCHAL_XLMI0_VADDR 0x3FF00000 +#define XCHAL_XLMI0_PADDR 0x3FF00000 +#define XCHAL_XLMI0_SIZE 262144 +#define XCHAL_XLMI0_ECC_PARITY 0 + + +/*---------------------------------------------------------------------- + INTERRUPTS and TIMERS + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */ +#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ +#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */ +#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */ +#define XCHAL_NUM_TIMERS 1 /* number of CCOMPAREn regs */ +#define XCHAL_NUM_INTERRUPTS 15 /* number of interrupts */ +#define XCHAL_NUM_INTERRUPTS_LOG2 4 /* ceil(log2(NUM_INTERRUPTS)) */ +#define XCHAL_NUM_EXTINTERRUPTS 13 /* num of external interrupts */ +#define XCHAL_NUM_INTLEVELS 2 /* number of interrupt levels + (not including level zero) */ +#define XCHAL_EXCM_LEVEL 1 /* level masked by PS.EXCM */ + /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */ + +/* Masks of interrupts at each interrupt level: */ +#define XCHAL_INTLEVEL1_MASK 0x00003FFF +#define XCHAL_INTLEVEL2_MASK 0x00000000 +#define XCHAL_INTLEVEL3_MASK 0x00004000 +#define XCHAL_INTLEVEL4_MASK 0x00000000 +#define XCHAL_INTLEVEL5_MASK 0x00000000 +#define XCHAL_INTLEVEL6_MASK 0x00000000 +#define XCHAL_INTLEVEL7_MASK 0x00000000 + +/* Masks of interrupts at each range 1..n of interrupt levels: */ +#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x00003FFF +#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x00003FFF +#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x00007FFF +#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x00007FFF +#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x00007FFF +#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x00007FFF +#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x00007FFF + +/* Level of each interrupt: */ +#define XCHAL_INT0_LEVEL 1 +#define XCHAL_INT1_LEVEL 1 +#define XCHAL_INT2_LEVEL 1 +#define XCHAL_INT3_LEVEL 1 +#define XCHAL_INT4_LEVEL 1 +#define XCHAL_INT5_LEVEL 1 +#define XCHAL_INT6_LEVEL 1 +#define XCHAL_INT7_LEVEL 1 +#define XCHAL_INT8_LEVEL 1 +#define XCHAL_INT9_LEVEL 1 +#define XCHAL_INT10_LEVEL 1 +#define XCHAL_INT11_LEVEL 1 +#define XCHAL_INT12_LEVEL 1 +#define XCHAL_INT13_LEVEL 1 +#define XCHAL_INT14_LEVEL 3 +#define XCHAL_DEBUGLEVEL 2 /* debug interrupt level */ +#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ +#define XCHAL_NMILEVEL 3 /* NMI "level" (for use with + EXCSAVE/EPS/EPC_n, RFI n) */ + +/* Type of each interrupt: */ +#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT7_TYPE XTHAL_INTTYPE_SOFTWARE +#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT10_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT11_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT13_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT14_TYPE XTHAL_INTTYPE_NMI + +/* Masks of interrupts for each type of interrupt: */ +#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFFF8000 +#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000080 +#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00003F00 +#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000003F +#define XCHAL_INTTYPE_MASK_TIMER 0x00000040 +#define XCHAL_INTTYPE_MASK_NMI 0x00004000 +#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000 + +/* Interrupt numbers assigned to specific interrupt sources: */ +#define XCHAL_TIMER0_INTERRUPT 6 /* CCOMPARE0 */ +#define XCHAL_TIMER1_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_TIMER2_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_NMI_INTERRUPT 14 /* non-maskable interrupt */ + +/* Interrupt numbers for levels at which only one interrupt is configured: */ +#define XCHAL_INTLEVEL3_NUM 14 +/* (There are many interrupts each at level(s) 1.) */ + + +/* + * External interrupt vectors/levels. + * These macros describe how Xtensa processor interrupt numbers + * (as numbered internally, eg. in INTERRUPT and INTENABLE registers) + * map to external BInterrupt pins, for those interrupts + * configured as external (level-triggered, edge-triggered, or NMI). + * See the Xtensa processor databook for more details. + */ + +/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */ +#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */ +#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */ +#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */ +#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */ +#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */ +#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */ +#define XCHAL_EXTINT6_NUM 8 /* (intlevel 1) */ +#define XCHAL_EXTINT7_NUM 9 /* (intlevel 1) */ +#define XCHAL_EXTINT8_NUM 10 /* (intlevel 1) */ +#define XCHAL_EXTINT9_NUM 11 /* (intlevel 1) */ +#define XCHAL_EXTINT10_NUM 12 /* (intlevel 1) */ +#define XCHAL_EXTINT11_NUM 13 /* (intlevel 1) */ +#define XCHAL_EXTINT12_NUM 14 /* (intlevel 3) */ + + +/*---------------------------------------------------------------------- + EXCEPTIONS and VECTORS + ----------------------------------------------------------------------*/ + +#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture + number: 1 == XEA1 (old) + 2 == XEA2 (new) + 0 == XEAX (extern) */ +#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */ +#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */ +#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */ +#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */ +#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */ +#define XCHAL_HAVE_VECTOR_SELECT 1 /* relocatable vectors */ +#define XCHAL_HAVE_VECBASE 1 /* relocatable vectors */ +#define XCHAL_VECBASE_RESET_VADDR 0x40000000 /* VECBASE reset value */ +#define XCHAL_VECBASE_RESET_PADDR 0x40000000 +#define XCHAL_RESET_VECBASE_OVERLAP 0 + +#define XCHAL_RESET_VECTOR0_VADDR 0x50000000 +#define XCHAL_RESET_VECTOR0_PADDR 0x50000000 +#define XCHAL_RESET_VECTOR1_VADDR 0x40000080 +#define XCHAL_RESET_VECTOR1_PADDR 0x40000080 +#define XCHAL_RESET_VECTOR_VADDR 0x50000000 +#define XCHAL_RESET_VECTOR_PADDR 0x50000000 +#define XCHAL_USER_VECOFS 0x00000050 +#define XCHAL_USER_VECTOR_VADDR 0x40000050 +#define XCHAL_USER_VECTOR_PADDR 0x40000050 +#define XCHAL_KERNEL_VECOFS 0x00000030 +#define XCHAL_KERNEL_VECTOR_VADDR 0x40000030 +#define XCHAL_KERNEL_VECTOR_PADDR 0x40000030 +#define XCHAL_DOUBLEEXC_VECOFS 0x00000070 +#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x40000070 +#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x40000070 +#define XCHAL_INTLEVEL2_VECOFS 0x00000010 +#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x40000010 +#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x40000010 +#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL2_VECOFS +#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL2_VECTOR_VADDR +#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL2_VECTOR_PADDR +#define XCHAL_NMI_VECOFS 0x00000020 +#define XCHAL_NMI_VECTOR_VADDR 0x40000020 +#define XCHAL_NMI_VECTOR_PADDR 0x40000020 +#define XCHAL_INTLEVEL3_VECOFS XCHAL_NMI_VECOFS +#define XCHAL_INTLEVEL3_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR +#define XCHAL_INTLEVEL3_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR + + +/*---------------------------------------------------------------------- + DEBUG + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */ +#define XCHAL_NUM_IBREAK 1 /* number of IBREAKn regs */ +#define XCHAL_NUM_DBREAK 1 /* number of DBREAKn regs */ +#define XCHAL_HAVE_OCD_DIR_ARRAY 0 /* faster OCD option */ + + +/*---------------------------------------------------------------------- + MMU + ----------------------------------------------------------------------*/ + +/* See core-matmap.h header file for more details. */ + +#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */ +#define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */ +#define XCHAL_SPANNING_WAY 0 /* TLB spanning way number */ +#define XCHAL_HAVE_IDENTITY_MAP 1 /* vaddr == paddr always */ +#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */ +#define XCHAL_HAVE_MIMIC_CACHEATTR 1 /* region protection */ +#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */ +#define XCHAL_HAVE_PTP_MMU 0 /* full MMU (with page table + [autorefill] and protection) + usable for an MMU-based OS */ +/* If none of the above last 4 are set, it's a custom TLB configuration. */ + +#define XCHAL_MMU_ASID_BITS 0 /* number of bits in ASIDs */ +#define XCHAL_MMU_RINGS 1 /* number of rings (1..4) */ +#define XCHAL_MMU_RING_BITS 0 /* num of bits in RING field */ + +#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ + + +#endif /* _XTENSA_CORE_CONFIGURATION_H */ + diff --git a/extra_include/xtensa/config/core-matmap.h b/extra_include/xtensa/config/core-matmap.h index 8e31a272..b2137d14 100644 --- a/extra_include/xtensa/config/core-matmap.h +++ b/extra_include/xtensa/config/core-matmap.h @@ -1,316 +1,316 @@ -/* - * xtensa/config/core-matmap.h -- Memory access and translation mapping - * parameters (CHAL) of the Xtensa processor core configuration. - * - * If you are using Xtensa Tools, see (which includes - * this file) for more details. - * - * In the Xtensa processor products released to date, all parameters - * defined in this file are derivable (at least in theory) from - * information contained in the core-isa.h header file. - * In particular, the following core configuration parameters are relevant: - * XCHAL_HAVE_CACHEATTR - * XCHAL_HAVE_MIMIC_CACHEATTR - * XCHAL_HAVE_XLT_CACHEATTR - * XCHAL_HAVE_PTP_MMU - * XCHAL_ITLB_ARF_ENTRIES_LOG2 - * XCHAL_DTLB_ARF_ENTRIES_LOG2 - * XCHAL_DCACHE_IS_WRITEBACK - * XCHAL_ICACHE_SIZE (presence of I-cache) - * XCHAL_DCACHE_SIZE (presence of D-cache) - * XCHAL_HW_VERSION_MAJOR - * XCHAL_HW_VERSION_MINOR - */ - -/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 1999-2010 Tensilica Inc. - - 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 XTENSA_CONFIG_CORE_MATMAP_H -#define XTENSA_CONFIG_CORE_MATMAP_H - - -/*---------------------------------------------------------------------- - CACHE (MEMORY ACCESS) ATTRIBUTES - ----------------------------------------------------------------------*/ - - -/* Cache Attribute encodings -- lists of access modes for each cache attribute: */ -#define XCHAL_FCA_LIST XTHAL_FAM_EXCEPTION XCHAL_SEP \ - XTHAL_FAM_BYPASS XCHAL_SEP \ - XTHAL_FAM_BYPASS XCHAL_SEP \ - XTHAL_FAM_BYPASS XCHAL_SEP \ - XTHAL_FAM_BYPASS XCHAL_SEP \ - XTHAL_FAM_BYPASS XCHAL_SEP \ - XTHAL_FAM_EXCEPTION XCHAL_SEP \ - XTHAL_FAM_EXCEPTION XCHAL_SEP \ - XTHAL_FAM_EXCEPTION XCHAL_SEP \ - XTHAL_FAM_EXCEPTION XCHAL_SEP \ - XTHAL_FAM_EXCEPTION XCHAL_SEP \ - XTHAL_FAM_EXCEPTION XCHAL_SEP \ - XTHAL_FAM_EXCEPTION XCHAL_SEP \ - XTHAL_FAM_EXCEPTION XCHAL_SEP \ - XTHAL_FAM_EXCEPTION XCHAL_SEP \ - XTHAL_FAM_EXCEPTION -#define XCHAL_LCA_LIST XTHAL_LAM_BYPASSG XCHAL_SEP \ - XTHAL_LAM_BYPASSG XCHAL_SEP \ - XTHAL_LAM_BYPASSG XCHAL_SEP \ - XTHAL_LAM_EXCEPTION XCHAL_SEP \ - XTHAL_LAM_BYPASSG XCHAL_SEP \ - XTHAL_LAM_BYPASSG XCHAL_SEP \ - XTHAL_LAM_EXCEPTION XCHAL_SEP \ - XTHAL_LAM_EXCEPTION XCHAL_SEP \ - XTHAL_LAM_EXCEPTION XCHAL_SEP \ - XTHAL_LAM_EXCEPTION XCHAL_SEP \ - XTHAL_LAM_EXCEPTION XCHAL_SEP \ - XTHAL_LAM_EXCEPTION XCHAL_SEP \ - XTHAL_LAM_EXCEPTION XCHAL_SEP \ - XTHAL_LAM_EXCEPTION XCHAL_SEP \ - XTHAL_LAM_BYPASSG XCHAL_SEP \ - XTHAL_LAM_EXCEPTION -#define XCHAL_SCA_LIST XTHAL_SAM_BYPASS XCHAL_SEP \ - XTHAL_SAM_BYPASS XCHAL_SEP \ - XTHAL_SAM_BYPASS XCHAL_SEP \ - XTHAL_SAM_EXCEPTION XCHAL_SEP \ - XTHAL_SAM_BYPASS XCHAL_SEP \ - XTHAL_SAM_BYPASS XCHAL_SEP \ - XTHAL_SAM_EXCEPTION XCHAL_SEP \ - XTHAL_SAM_EXCEPTION XCHAL_SEP \ - XTHAL_SAM_EXCEPTION XCHAL_SEP \ - XTHAL_SAM_EXCEPTION XCHAL_SEP \ - XTHAL_SAM_EXCEPTION XCHAL_SEP \ - XTHAL_SAM_EXCEPTION XCHAL_SEP \ - XTHAL_SAM_EXCEPTION XCHAL_SEP \ - XTHAL_SAM_EXCEPTION XCHAL_SEP \ - XTHAL_SAM_BYPASS XCHAL_SEP \ - XTHAL_SAM_EXCEPTION - - -/* - * Specific encoded cache attribute values of general interest. - * If a specific cache mode is not available, the closest available - * one is returned instead (eg. writethru instead of writeback, - * bypass instead of writethru). - */ -#define XCHAL_CA_BYPASS 2 /* cache disabled (bypassed) mode */ -#define XCHAL_CA_WRITETHRU 2 /* cache enabled (write-through) mode */ -#define XCHAL_CA_WRITEBACK 2 /* cache enabled (write-back) mode */ -#define XCHAL_CA_WRITEBACK_NOALLOC 2 /* cache enabled (write-back no-allocate) mode */ -#define XCHAL_CA_BYPASS_RW 0 /* cache disabled (bypassed) mode (no exec) */ -#define XCHAL_CA_WRITETHRU_RW 0 /* cache enabled (write-through) mode (no exec) */ -#define XCHAL_CA_WRITEBACK_RW 0 /* cache enabled (write-back) mode (no exec) */ -#define XCHAL_CA_WRITEBACK_NOALLOC_RW 0 /* cache enabled (write-back no-allocate) mode (no exec) */ -#define XCHAL_CA_ILLEGAL 15 /* no access allowed (all cause exceptions) mode */ -#define XCHAL_CA_ISOLATE 0 /* cache isolate (accesses go to cache not memory) mode */ - - -/*---------------------------------------------------------------------- - MMU - ----------------------------------------------------------------------*/ - -/* - * General notes on MMU parameters. - * - * Terminology: - * ASID = address-space ID (acts as an "extension" of virtual addresses) - * VPN = virtual page number - * PPN = physical page number - * CA = encoded cache attribute (access modes) - * TLB = translation look-aside buffer (term is stretched somewhat here) - * I = instruction (fetch accesses) - * D = data (load and store accesses) - * way = each TLB (ITLB and DTLB) consists of a number of "ways" - * that simultaneously match the virtual address of an access; - * a TLB successfully translates a virtual address if exactly - * one way matches the vaddr; if none match, it is a miss; - * if multiple match, one gets a "multihit" exception; - * each way can be independently configured in terms of number of - * entries, page sizes, which fields are writable or constant, etc. - * set = group of contiguous ways with exactly identical parameters - * ARF = auto-refill; hardware services a 1st-level miss by loading a PTE - * from the page table and storing it in one of the auto-refill ways; - * if this PTE load also misses, a miss exception is posted for s/w. - * min-wired = a "min-wired" way can be used to map a single (minimum-sized) - * page arbitrarily under program control; it has a single entry, - * is non-auto-refill (some other way(s) must be auto-refill), - * all its fields (VPN, PPN, ASID, CA) are all writable, and it - * supports the XCHAL_MMU_MIN_PTE_PAGE_SIZE page size (a current - * restriction is that this be the only page size it supports). - * - * TLB way entries are virtually indexed. - * TLB ways that support multiple page sizes: - * - must have all writable VPN and PPN fields; - * - can only use one page size at any given time (eg. setup at startup), - * selected by the respective ITLBCFG or DTLBCFG special register, - * whose bits n*4+3 .. n*4 index the list of page sizes for way n - * (XCHAL_xTLB_SETm_PAGESZ_LOG2_LIST for set m corresponding to way n); - * this list may be sparse for auto-refill ways because auto-refill - * ways have independent lists of supported page sizes sharing a - * common encoding with PTE entries; the encoding is the index into - * this list; unsupported sizes for a given way are zero in the list; - * selecting unsupported sizes results in undefined hardware behaviour; - * - is only possible for ways 0 thru 7 (due to ITLBCFG/DTLBCFG definition). - */ - -#define XCHAL_MMU_ASID_INVALID 0 /* ASID value indicating invalid address space */ -#define XCHAL_MMU_ASID_KERNEL 0 /* ASID value indicating kernel (ring 0) address space */ -#define XCHAL_MMU_SR_BITS 0 /* number of size-restriction bits supported */ -#define XCHAL_MMU_CA_BITS 4 /* number of bits needed to hold cache attribute encoding */ -#define XCHAL_MMU_MAX_PTE_PAGE_SIZE 29 /* max page size in a PTE structure (log2) */ -#define XCHAL_MMU_MIN_PTE_PAGE_SIZE 29 /* min page size in a PTE structure (log2) */ - - -/*** Instruction TLB: ***/ - -#define XCHAL_ITLB_WAY_BITS 0 /* number of bits holding the ways */ -#define XCHAL_ITLB_WAYS 1 /* number of ways (n-way set-associative TLB) */ -#define XCHAL_ITLB_ARF_WAYS 0 /* number of auto-refill ways */ -#define XCHAL_ITLB_SETS 1 /* number of sets (groups of ways with identical settings) */ - -/* Way set to which each way belongs: */ -#define XCHAL_ITLB_WAY0_SET 0 - -/* Ways sets that are used by hardware auto-refill (ARF): */ -#define XCHAL_ITLB_ARF_SETS 0 /* number of auto-refill sets */ - -/* Way sets that are "min-wired" (see terminology comment above): */ -#define XCHAL_ITLB_MINWIRED_SETS 0 /* number of "min-wired" sets */ - - -/* ITLB way set 0 (group of ways 0 thru 0): */ -#define XCHAL_ITLB_SET0_WAY 0 /* index of first way in this way set */ -#define XCHAL_ITLB_SET0_WAYS 1 /* number of (contiguous) ways in this way set */ -#define XCHAL_ITLB_SET0_ENTRIES_LOG2 3 /* log2(number of entries in this way) */ -#define XCHAL_ITLB_SET0_ENTRIES 8 /* number of entries in this way (always a power of 2) */ -#define XCHAL_ITLB_SET0_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */ -#define XCHAL_ITLB_SET0_PAGESIZES 1 /* number of supported page sizes in this way */ -#define XCHAL_ITLB_SET0_PAGESZ_BITS 0 /* number of bits to encode the page size */ -#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MIN 29 /* log2(minimum supported page size) */ -#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MAX 29 /* log2(maximum supported page size) */ -#define XCHAL_ITLB_SET0_PAGESZ_LOG2_LIST 29 /* list of log2(page size)s, separated by XCHAL_SEP; - 2^PAGESZ_BITS entries in list, unsupported entries are zero */ -#define XCHAL_ITLB_SET0_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */ -#define XCHAL_ITLB_SET0_VPN_CONSTMASK 0x00000000 /* constant VPN bits, not including entry index bits; 0 if all writable */ -#define XCHAL_ITLB_SET0_PPN_CONSTMASK 0xE0000000 /* constant PPN bits, including entry index bits; 0 if all writable */ -#define XCHAL_ITLB_SET0_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */ -#define XCHAL_ITLB_SET0_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */ -#define XCHAL_ITLB_SET0_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */ -#define XCHAL_ITLB_SET0_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */ -#define XCHAL_ITLB_SET0_CA_RESET 1 /* 1 if CA reset values defined (and all writable); 0 otherwise */ -/* Constant VPN values for each entry of ITLB way set 0 (because VPN_CONSTMASK is non-zero): */ -#define XCHAL_ITLB_SET0_E0_VPN_CONST 0x00000000 -#define XCHAL_ITLB_SET0_E1_VPN_CONST 0x20000000 -#define XCHAL_ITLB_SET0_E2_VPN_CONST 0x40000000 -#define XCHAL_ITLB_SET0_E3_VPN_CONST 0x60000000 -#define XCHAL_ITLB_SET0_E4_VPN_CONST 0x80000000 -#define XCHAL_ITLB_SET0_E5_VPN_CONST 0xA0000000 -#define XCHAL_ITLB_SET0_E6_VPN_CONST 0xC0000000 -#define XCHAL_ITLB_SET0_E7_VPN_CONST 0xE0000000 -/* Constant PPN values for each entry of ITLB way set 0 (because PPN_CONSTMASK is non-zero): */ -#define XCHAL_ITLB_SET0_E0_PPN_CONST 0x00000000 -#define XCHAL_ITLB_SET0_E1_PPN_CONST 0x20000000 -#define XCHAL_ITLB_SET0_E2_PPN_CONST 0x40000000 -#define XCHAL_ITLB_SET0_E3_PPN_CONST 0x60000000 -#define XCHAL_ITLB_SET0_E4_PPN_CONST 0x80000000 -#define XCHAL_ITLB_SET0_E5_PPN_CONST 0xA0000000 -#define XCHAL_ITLB_SET0_E6_PPN_CONST 0xC0000000 -#define XCHAL_ITLB_SET0_E7_PPN_CONST 0xE0000000 -/* Reset CA values for each entry of ITLB way set 0 (because SET0_CA_RESET is non-zero): */ -#define XCHAL_ITLB_SET0_E0_CA_RESET 0x02 -#define XCHAL_ITLB_SET0_E1_CA_RESET 0x02 -#define XCHAL_ITLB_SET0_E2_CA_RESET 0x02 -#define XCHAL_ITLB_SET0_E3_CA_RESET 0x02 -#define XCHAL_ITLB_SET0_E4_CA_RESET 0x02 -#define XCHAL_ITLB_SET0_E5_CA_RESET 0x02 -#define XCHAL_ITLB_SET0_E6_CA_RESET 0x02 -#define XCHAL_ITLB_SET0_E7_CA_RESET 0x02 - - -/*** Data TLB: ***/ - -#define XCHAL_DTLB_WAY_BITS 0 /* number of bits holding the ways */ -#define XCHAL_DTLB_WAYS 1 /* number of ways (n-way set-associative TLB) */ -#define XCHAL_DTLB_ARF_WAYS 0 /* number of auto-refill ways */ -#define XCHAL_DTLB_SETS 1 /* number of sets (groups of ways with identical settings) */ - -/* Way set to which each way belongs: */ -#define XCHAL_DTLB_WAY0_SET 0 - -/* Ways sets that are used by hardware auto-refill (ARF): */ -#define XCHAL_DTLB_ARF_SETS 0 /* number of auto-refill sets */ - -/* Way sets that are "min-wired" (see terminology comment above): */ -#define XCHAL_DTLB_MINWIRED_SETS 0 /* number of "min-wired" sets */ - - -/* DTLB way set 0 (group of ways 0 thru 0): */ -#define XCHAL_DTLB_SET0_WAY 0 /* index of first way in this way set */ -#define XCHAL_DTLB_SET0_WAYS 1 /* number of (contiguous) ways in this way set */ -#define XCHAL_DTLB_SET0_ENTRIES_LOG2 3 /* log2(number of entries in this way) */ -#define XCHAL_DTLB_SET0_ENTRIES 8 /* number of entries in this way (always a power of 2) */ -#define XCHAL_DTLB_SET0_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */ -#define XCHAL_DTLB_SET0_PAGESIZES 1 /* number of supported page sizes in this way */ -#define XCHAL_DTLB_SET0_PAGESZ_BITS 0 /* number of bits to encode the page size */ -#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MIN 29 /* log2(minimum supported page size) */ -#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MAX 29 /* log2(maximum supported page size) */ -#define XCHAL_DTLB_SET0_PAGESZ_LOG2_LIST 29 /* list of log2(page size)s, separated by XCHAL_SEP; - 2^PAGESZ_BITS entries in list, unsupported entries are zero */ -#define XCHAL_DTLB_SET0_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */ -#define XCHAL_DTLB_SET0_VPN_CONSTMASK 0x00000000 /* constant VPN bits, not including entry index bits; 0 if all writable */ -#define XCHAL_DTLB_SET0_PPN_CONSTMASK 0xE0000000 /* constant PPN bits, including entry index bits; 0 if all writable */ -#define XCHAL_DTLB_SET0_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */ -#define XCHAL_DTLB_SET0_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */ -#define XCHAL_DTLB_SET0_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */ -#define XCHAL_DTLB_SET0_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */ -#define XCHAL_DTLB_SET0_CA_RESET 1 /* 1 if CA reset values defined (and all writable); 0 otherwise */ -/* Constant VPN values for each entry of DTLB way set 0 (because VPN_CONSTMASK is non-zero): */ -#define XCHAL_DTLB_SET0_E0_VPN_CONST 0x00000000 -#define XCHAL_DTLB_SET0_E1_VPN_CONST 0x20000000 -#define XCHAL_DTLB_SET0_E2_VPN_CONST 0x40000000 -#define XCHAL_DTLB_SET0_E3_VPN_CONST 0x60000000 -#define XCHAL_DTLB_SET0_E4_VPN_CONST 0x80000000 -#define XCHAL_DTLB_SET0_E5_VPN_CONST 0xA0000000 -#define XCHAL_DTLB_SET0_E6_VPN_CONST 0xC0000000 -#define XCHAL_DTLB_SET0_E7_VPN_CONST 0xE0000000 -/* Constant PPN values for each entry of DTLB way set 0 (because PPN_CONSTMASK is non-zero): */ -#define XCHAL_DTLB_SET0_E0_PPN_CONST 0x00000000 -#define XCHAL_DTLB_SET0_E1_PPN_CONST 0x20000000 -#define XCHAL_DTLB_SET0_E2_PPN_CONST 0x40000000 -#define XCHAL_DTLB_SET0_E3_PPN_CONST 0x60000000 -#define XCHAL_DTLB_SET0_E4_PPN_CONST 0x80000000 -#define XCHAL_DTLB_SET0_E5_PPN_CONST 0xA0000000 -#define XCHAL_DTLB_SET0_E6_PPN_CONST 0xC0000000 -#define XCHAL_DTLB_SET0_E7_PPN_CONST 0xE0000000 -/* Reset CA values for each entry of DTLB way set 0 (because SET0_CA_RESET is non-zero): */ -#define XCHAL_DTLB_SET0_E0_CA_RESET 0x02 -#define XCHAL_DTLB_SET0_E1_CA_RESET 0x02 -#define XCHAL_DTLB_SET0_E2_CA_RESET 0x02 -#define XCHAL_DTLB_SET0_E3_CA_RESET 0x02 -#define XCHAL_DTLB_SET0_E4_CA_RESET 0x02 -#define XCHAL_DTLB_SET0_E5_CA_RESET 0x02 -#define XCHAL_DTLB_SET0_E6_CA_RESET 0x02 -#define XCHAL_DTLB_SET0_E7_CA_RESET 0x02 - - - - -#endif /*XTENSA_CONFIG_CORE_MATMAP_H*/ - +/* + * xtensa/config/core-matmap.h -- Memory access and translation mapping + * parameters (CHAL) of the Xtensa processor core configuration. + * + * If you are using Xtensa Tools, see (which includes + * this file) for more details. + * + * In the Xtensa processor products released to date, all parameters + * defined in this file are derivable (at least in theory) from + * information contained in the core-isa.h header file. + * In particular, the following core configuration parameters are relevant: + * XCHAL_HAVE_CACHEATTR + * XCHAL_HAVE_MIMIC_CACHEATTR + * XCHAL_HAVE_XLT_CACHEATTR + * XCHAL_HAVE_PTP_MMU + * XCHAL_ITLB_ARF_ENTRIES_LOG2 + * XCHAL_DTLB_ARF_ENTRIES_LOG2 + * XCHAL_DCACHE_IS_WRITEBACK + * XCHAL_ICACHE_SIZE (presence of I-cache) + * XCHAL_DCACHE_SIZE (presence of D-cache) + * XCHAL_HW_VERSION_MAJOR + * XCHAL_HW_VERSION_MINOR + */ + +/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 1999-2010 Tensilica Inc. + + 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 XTENSA_CONFIG_CORE_MATMAP_H +#define XTENSA_CONFIG_CORE_MATMAP_H + + +/*---------------------------------------------------------------------- + CACHE (MEMORY ACCESS) ATTRIBUTES + ----------------------------------------------------------------------*/ + + +/* Cache Attribute encodings -- lists of access modes for each cache attribute: */ +#define XCHAL_FCA_LIST XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_BYPASS XCHAL_SEP \ + XTHAL_FAM_BYPASS XCHAL_SEP \ + XTHAL_FAM_BYPASS XCHAL_SEP \ + XTHAL_FAM_BYPASS XCHAL_SEP \ + XTHAL_FAM_BYPASS XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION XCHAL_SEP \ + XTHAL_FAM_EXCEPTION +#define XCHAL_LCA_LIST XTHAL_LAM_BYPASSG XCHAL_SEP \ + XTHAL_LAM_BYPASSG XCHAL_SEP \ + XTHAL_LAM_BYPASSG XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_BYPASSG XCHAL_SEP \ + XTHAL_LAM_BYPASSG XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_EXCEPTION XCHAL_SEP \ + XTHAL_LAM_BYPASSG XCHAL_SEP \ + XTHAL_LAM_EXCEPTION +#define XCHAL_SCA_LIST XTHAL_SAM_BYPASS XCHAL_SEP \ + XTHAL_SAM_BYPASS XCHAL_SEP \ + XTHAL_SAM_BYPASS XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_BYPASS XCHAL_SEP \ + XTHAL_SAM_BYPASS XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_EXCEPTION XCHAL_SEP \ + XTHAL_SAM_BYPASS XCHAL_SEP \ + XTHAL_SAM_EXCEPTION + + +/* + * Specific encoded cache attribute values of general interest. + * If a specific cache mode is not available, the closest available + * one is returned instead (eg. writethru instead of writeback, + * bypass instead of writethru). + */ +#define XCHAL_CA_BYPASS 2 /* cache disabled (bypassed) mode */ +#define XCHAL_CA_WRITETHRU 2 /* cache enabled (write-through) mode */ +#define XCHAL_CA_WRITEBACK 2 /* cache enabled (write-back) mode */ +#define XCHAL_CA_WRITEBACK_NOALLOC 2 /* cache enabled (write-back no-allocate) mode */ +#define XCHAL_CA_BYPASS_RW 0 /* cache disabled (bypassed) mode (no exec) */ +#define XCHAL_CA_WRITETHRU_RW 0 /* cache enabled (write-through) mode (no exec) */ +#define XCHAL_CA_WRITEBACK_RW 0 /* cache enabled (write-back) mode (no exec) */ +#define XCHAL_CA_WRITEBACK_NOALLOC_RW 0 /* cache enabled (write-back no-allocate) mode (no exec) */ +#define XCHAL_CA_ILLEGAL 15 /* no access allowed (all cause exceptions) mode */ +#define XCHAL_CA_ISOLATE 0 /* cache isolate (accesses go to cache not memory) mode */ + + +/*---------------------------------------------------------------------- + MMU + ----------------------------------------------------------------------*/ + +/* + * General notes on MMU parameters. + * + * Terminology: + * ASID = address-space ID (acts as an "extension" of virtual addresses) + * VPN = virtual page number + * PPN = physical page number + * CA = encoded cache attribute (access modes) + * TLB = translation look-aside buffer (term is stretched somewhat here) + * I = instruction (fetch accesses) + * D = data (load and store accesses) + * way = each TLB (ITLB and DTLB) consists of a number of "ways" + * that simultaneously match the virtual address of an access; + * a TLB successfully translates a virtual address if exactly + * one way matches the vaddr; if none match, it is a miss; + * if multiple match, one gets a "multihit" exception; + * each way can be independently configured in terms of number of + * entries, page sizes, which fields are writable or constant, etc. + * set = group of contiguous ways with exactly identical parameters + * ARF = auto-refill; hardware services a 1st-level miss by loading a PTE + * from the page table and storing it in one of the auto-refill ways; + * if this PTE load also misses, a miss exception is posted for s/w. + * min-wired = a "min-wired" way can be used to map a single (minimum-sized) + * page arbitrarily under program control; it has a single entry, + * is non-auto-refill (some other way(s) must be auto-refill), + * all its fields (VPN, PPN, ASID, CA) are all writable, and it + * supports the XCHAL_MMU_MIN_PTE_PAGE_SIZE page size (a current + * restriction is that this be the only page size it supports). + * + * TLB way entries are virtually indexed. + * TLB ways that support multiple page sizes: + * - must have all writable VPN and PPN fields; + * - can only use one page size at any given time (eg. setup at startup), + * selected by the respective ITLBCFG or DTLBCFG special register, + * whose bits n*4+3 .. n*4 index the list of page sizes for way n + * (XCHAL_xTLB_SETm_PAGESZ_LOG2_LIST for set m corresponding to way n); + * this list may be sparse for auto-refill ways because auto-refill + * ways have independent lists of supported page sizes sharing a + * common encoding with PTE entries; the encoding is the index into + * this list; unsupported sizes for a given way are zero in the list; + * selecting unsupported sizes results in undefined hardware behaviour; + * - is only possible for ways 0 thru 7 (due to ITLBCFG/DTLBCFG definition). + */ + +#define XCHAL_MMU_ASID_INVALID 0 /* ASID value indicating invalid address space */ +#define XCHAL_MMU_ASID_KERNEL 0 /* ASID value indicating kernel (ring 0) address space */ +#define XCHAL_MMU_SR_BITS 0 /* number of size-restriction bits supported */ +#define XCHAL_MMU_CA_BITS 4 /* number of bits needed to hold cache attribute encoding */ +#define XCHAL_MMU_MAX_PTE_PAGE_SIZE 29 /* max page size in a PTE structure (log2) */ +#define XCHAL_MMU_MIN_PTE_PAGE_SIZE 29 /* min page size in a PTE structure (log2) */ + + +/*** Instruction TLB: ***/ + +#define XCHAL_ITLB_WAY_BITS 0 /* number of bits holding the ways */ +#define XCHAL_ITLB_WAYS 1 /* number of ways (n-way set-associative TLB) */ +#define XCHAL_ITLB_ARF_WAYS 0 /* number of auto-refill ways */ +#define XCHAL_ITLB_SETS 1 /* number of sets (groups of ways with identical settings) */ + +/* Way set to which each way belongs: */ +#define XCHAL_ITLB_WAY0_SET 0 + +/* Ways sets that are used by hardware auto-refill (ARF): */ +#define XCHAL_ITLB_ARF_SETS 0 /* number of auto-refill sets */ + +/* Way sets that are "min-wired" (see terminology comment above): */ +#define XCHAL_ITLB_MINWIRED_SETS 0 /* number of "min-wired" sets */ + + +/* ITLB way set 0 (group of ways 0 thru 0): */ +#define XCHAL_ITLB_SET0_WAY 0 /* index of first way in this way set */ +#define XCHAL_ITLB_SET0_WAYS 1 /* number of (contiguous) ways in this way set */ +#define XCHAL_ITLB_SET0_ENTRIES_LOG2 3 /* log2(number of entries in this way) */ +#define XCHAL_ITLB_SET0_ENTRIES 8 /* number of entries in this way (always a power of 2) */ +#define XCHAL_ITLB_SET0_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */ +#define XCHAL_ITLB_SET0_PAGESIZES 1 /* number of supported page sizes in this way */ +#define XCHAL_ITLB_SET0_PAGESZ_BITS 0 /* number of bits to encode the page size */ +#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MIN 29 /* log2(minimum supported page size) */ +#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MAX 29 /* log2(maximum supported page size) */ +#define XCHAL_ITLB_SET0_PAGESZ_LOG2_LIST 29 /* list of log2(page size)s, separated by XCHAL_SEP; + 2^PAGESZ_BITS entries in list, unsupported entries are zero */ +#define XCHAL_ITLB_SET0_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_VPN_CONSTMASK 0x00000000 /* constant VPN bits, not including entry index bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_PPN_CONSTMASK 0xE0000000 /* constant PPN bits, including entry index bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */ +#define XCHAL_ITLB_SET0_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */ +#define XCHAL_ITLB_SET0_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_ITLB_SET0_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_ITLB_SET0_CA_RESET 1 /* 1 if CA reset values defined (and all writable); 0 otherwise */ +/* Constant VPN values for each entry of ITLB way set 0 (because VPN_CONSTMASK is non-zero): */ +#define XCHAL_ITLB_SET0_E0_VPN_CONST 0x00000000 +#define XCHAL_ITLB_SET0_E1_VPN_CONST 0x20000000 +#define XCHAL_ITLB_SET0_E2_VPN_CONST 0x40000000 +#define XCHAL_ITLB_SET0_E3_VPN_CONST 0x60000000 +#define XCHAL_ITLB_SET0_E4_VPN_CONST 0x80000000 +#define XCHAL_ITLB_SET0_E5_VPN_CONST 0xA0000000 +#define XCHAL_ITLB_SET0_E6_VPN_CONST 0xC0000000 +#define XCHAL_ITLB_SET0_E7_VPN_CONST 0xE0000000 +/* Constant PPN values for each entry of ITLB way set 0 (because PPN_CONSTMASK is non-zero): */ +#define XCHAL_ITLB_SET0_E0_PPN_CONST 0x00000000 +#define XCHAL_ITLB_SET0_E1_PPN_CONST 0x20000000 +#define XCHAL_ITLB_SET0_E2_PPN_CONST 0x40000000 +#define XCHAL_ITLB_SET0_E3_PPN_CONST 0x60000000 +#define XCHAL_ITLB_SET0_E4_PPN_CONST 0x80000000 +#define XCHAL_ITLB_SET0_E5_PPN_CONST 0xA0000000 +#define XCHAL_ITLB_SET0_E6_PPN_CONST 0xC0000000 +#define XCHAL_ITLB_SET0_E7_PPN_CONST 0xE0000000 +/* Reset CA values for each entry of ITLB way set 0 (because SET0_CA_RESET is non-zero): */ +#define XCHAL_ITLB_SET0_E0_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E1_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E2_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E3_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E4_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E5_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E6_CA_RESET 0x02 +#define XCHAL_ITLB_SET0_E7_CA_RESET 0x02 + + +/*** Data TLB: ***/ + +#define XCHAL_DTLB_WAY_BITS 0 /* number of bits holding the ways */ +#define XCHAL_DTLB_WAYS 1 /* number of ways (n-way set-associative TLB) */ +#define XCHAL_DTLB_ARF_WAYS 0 /* number of auto-refill ways */ +#define XCHAL_DTLB_SETS 1 /* number of sets (groups of ways with identical settings) */ + +/* Way set to which each way belongs: */ +#define XCHAL_DTLB_WAY0_SET 0 + +/* Ways sets that are used by hardware auto-refill (ARF): */ +#define XCHAL_DTLB_ARF_SETS 0 /* number of auto-refill sets */ + +/* Way sets that are "min-wired" (see terminology comment above): */ +#define XCHAL_DTLB_MINWIRED_SETS 0 /* number of "min-wired" sets */ + + +/* DTLB way set 0 (group of ways 0 thru 0): */ +#define XCHAL_DTLB_SET0_WAY 0 /* index of first way in this way set */ +#define XCHAL_DTLB_SET0_WAYS 1 /* number of (contiguous) ways in this way set */ +#define XCHAL_DTLB_SET0_ENTRIES_LOG2 3 /* log2(number of entries in this way) */ +#define XCHAL_DTLB_SET0_ENTRIES 8 /* number of entries in this way (always a power of 2) */ +#define XCHAL_DTLB_SET0_ARF 0 /* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */ +#define XCHAL_DTLB_SET0_PAGESIZES 1 /* number of supported page sizes in this way */ +#define XCHAL_DTLB_SET0_PAGESZ_BITS 0 /* number of bits to encode the page size */ +#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MIN 29 /* log2(minimum supported page size) */ +#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MAX 29 /* log2(maximum supported page size) */ +#define XCHAL_DTLB_SET0_PAGESZ_LOG2_LIST 29 /* list of log2(page size)s, separated by XCHAL_SEP; + 2^PAGESZ_BITS entries in list, unsupported entries are zero */ +#define XCHAL_DTLB_SET0_ASID_CONSTMASK 0 /* constant ASID bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_VPN_CONSTMASK 0x00000000 /* constant VPN bits, not including entry index bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_PPN_CONSTMASK 0xE0000000 /* constant PPN bits, including entry index bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_CA_CONSTMASK 0 /* constant CA bits; 0 if all writable */ +#define XCHAL_DTLB_SET0_ASID_RESET 0 /* 1 if ASID reset values defined (and all writable); 0 otherwise */ +#define XCHAL_DTLB_SET0_VPN_RESET 0 /* 1 if VPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_DTLB_SET0_PPN_RESET 0 /* 1 if PPN reset values defined (and all writable); 0 otherwise */ +#define XCHAL_DTLB_SET0_CA_RESET 1 /* 1 if CA reset values defined (and all writable); 0 otherwise */ +/* Constant VPN values for each entry of DTLB way set 0 (because VPN_CONSTMASK is non-zero): */ +#define XCHAL_DTLB_SET0_E0_VPN_CONST 0x00000000 +#define XCHAL_DTLB_SET0_E1_VPN_CONST 0x20000000 +#define XCHAL_DTLB_SET0_E2_VPN_CONST 0x40000000 +#define XCHAL_DTLB_SET0_E3_VPN_CONST 0x60000000 +#define XCHAL_DTLB_SET0_E4_VPN_CONST 0x80000000 +#define XCHAL_DTLB_SET0_E5_VPN_CONST 0xA0000000 +#define XCHAL_DTLB_SET0_E6_VPN_CONST 0xC0000000 +#define XCHAL_DTLB_SET0_E7_VPN_CONST 0xE0000000 +/* Constant PPN values for each entry of DTLB way set 0 (because PPN_CONSTMASK is non-zero): */ +#define XCHAL_DTLB_SET0_E0_PPN_CONST 0x00000000 +#define XCHAL_DTLB_SET0_E1_PPN_CONST 0x20000000 +#define XCHAL_DTLB_SET0_E2_PPN_CONST 0x40000000 +#define XCHAL_DTLB_SET0_E3_PPN_CONST 0x60000000 +#define XCHAL_DTLB_SET0_E4_PPN_CONST 0x80000000 +#define XCHAL_DTLB_SET0_E5_PPN_CONST 0xA0000000 +#define XCHAL_DTLB_SET0_E6_PPN_CONST 0xC0000000 +#define XCHAL_DTLB_SET0_E7_PPN_CONST 0xE0000000 +/* Reset CA values for each entry of DTLB way set 0 (because SET0_CA_RESET is non-zero): */ +#define XCHAL_DTLB_SET0_E0_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E1_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E2_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E3_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E4_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E5_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E6_CA_RESET 0x02 +#define XCHAL_DTLB_SET0_E7_CA_RESET 0x02 + + + + +#endif /*XTENSA_CONFIG_CORE_MATMAP_H*/ + diff --git a/extra_include/xtensa/config/core.h b/extra_include/xtensa/config/core.h index f4593fb7..b2e72bd2 100644 --- a/extra_include/xtensa/config/core.h +++ b/extra_include/xtensa/config/core.h @@ -1,1328 +1,1328 @@ -/* - * xtensa/config/core.h -- HAL definitions dependent on CORE configuration - * - * This header file is sometimes referred to as the "compile-time HAL" or CHAL. - * It pulls definitions tailored for a specific Xtensa processor configuration. - * - * Sources for binaries meant to be configuration-independent generally avoid - * including this file (they may use the configuration-specific HAL library). - * It is normal for the HAL library source itself to include this file. - */ - -/* - * Copyright (c) 2005-2010 Tensilica Inc. - * - * 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 XTENSA_CONFIG_CORE_H -#define XTENSA_CONFIG_CORE_H - -/* CONFIGURATION INDEPENDENT DEFINITIONS: */ -#ifdef __XTENSA__ -#include -#else -#include "../hal.h" -#endif - -/* CONFIGURATION SPECIFIC DEFINITIONS: */ -#ifdef __XTENSA__ -#include -#include -#include -#else -#include "core-isa.h" -#include "core-matmap.h" -#include "tie.h" -#endif - -#if defined (_ASMLANGUAGE) || defined (__ASSEMBLER__) -#ifdef __XTENSA__ -#include -#else -#include "tie-asm.h" -#endif -#endif /*_ASMLANGUAGE or __ASSEMBLER__*/ - - -/*---------------------------------------------------------------------- - GENERAL - ----------------------------------------------------------------------*/ - -/* - * Separators for macros that expand into arrays. - * These can be predefined by files that #include this one, - * when different separators are required. - */ -/* Element separator for macros that expand into 1-dimensional arrays: */ -#ifndef XCHAL_SEP -#define XCHAL_SEP , -#endif -/* Array separator for macros that expand into 2-dimensional arrays: */ -#ifndef XCHAL_SEP2 -#define XCHAL_SEP2 },{ -#endif - - - -/*---------------------------------------------------------------------- - ISA - ----------------------------------------------------------------------*/ - -#if XCHAL_HAVE_BE -# define XCHAL_HAVE_LE 0 -# define XCHAL_MEMORY_ORDER XTHAL_BIGENDIAN -#else -# define XCHAL_HAVE_LE 1 -# define XCHAL_MEMORY_ORDER XTHAL_LITTLEENDIAN -#endif - - - -/*---------------------------------------------------------------------- - INTERRUPTS - ----------------------------------------------------------------------*/ - -/* Indexing macros: */ -#define _XCHAL_INTLEVEL_MASK(n) XCHAL_INTLEVEL ## n ## _MASK -#define XCHAL_INTLEVEL_MASK(n) _XCHAL_INTLEVEL_MASK(n) /* n = 0 .. 15 */ -#define _XCHAL_INTLEVEL_ANDBELOWMASK(n) XCHAL_INTLEVEL ## n ## _ANDBELOW_MASK -#define XCHAL_INTLEVEL_ANDBELOW_MASK(n) _XCHAL_INTLEVEL_ANDBELOWMASK(n) /* n = 0 .. 15 */ -#define _XCHAL_INTLEVEL_NUM(n) XCHAL_INTLEVEL ## n ## _NUM -#define XCHAL_INTLEVEL_NUM(n) _XCHAL_INTLEVEL_NUM(n) /* n = 0 .. 15 */ -#define _XCHAL_INT_LEVEL(n) XCHAL_INT ## n ## _LEVEL -#define XCHAL_INT_LEVEL(n) _XCHAL_INT_LEVEL(n) /* n = 0 .. 31 */ -#define _XCHAL_INT_TYPE(n) XCHAL_INT ## n ## _TYPE -#define XCHAL_INT_TYPE(n) _XCHAL_INT_TYPE(n) /* n = 0 .. 31 */ -#define _XCHAL_TIMER_INTERRUPT(n) XCHAL_TIMER ## n ## _INTERRUPT -#define XCHAL_TIMER_INTERRUPT(n) _XCHAL_TIMER_INTERRUPT(n) /* n = 0 .. 3 */ - - -#define XCHAL_HAVE_HIGHLEVEL_INTERRUPTS XCHAL_HAVE_HIGHPRI_INTERRUPTS -#define XCHAL_NUM_LOWPRI_LEVELS 1 /* number of low-priority interrupt levels (always 1) */ -#define XCHAL_FIRST_HIGHPRI_LEVEL (XCHAL_NUM_LOWPRI_LEVELS+1) /* level of first high-priority interrupt (always 2) */ -/* Note: 1 <= LOWPRI_LEVELS <= EXCM_LEVEL < DEBUGLEVEL <= NUM_INTLEVELS < NMILEVEL <= 15 */ - -/* These values are constant for existing Xtensa processor implementations: */ -#define XCHAL_INTLEVEL0_MASK 0x00000000 -#define XCHAL_INTLEVEL8_MASK 0x00000000 -#define XCHAL_INTLEVEL9_MASK 0x00000000 -#define XCHAL_INTLEVEL10_MASK 0x00000000 -#define XCHAL_INTLEVEL11_MASK 0x00000000 -#define XCHAL_INTLEVEL12_MASK 0x00000000 -#define XCHAL_INTLEVEL13_MASK 0x00000000 -#define XCHAL_INTLEVEL14_MASK 0x00000000 -#define XCHAL_INTLEVEL15_MASK 0x00000000 - -/* Array of masks of interrupts at each interrupt level: */ -#define XCHAL_INTLEVEL_MASKS XCHAL_INTLEVEL0_MASK \ - XCHAL_SEP XCHAL_INTLEVEL1_MASK \ - XCHAL_SEP XCHAL_INTLEVEL2_MASK \ - XCHAL_SEP XCHAL_INTLEVEL3_MASK \ - XCHAL_SEP XCHAL_INTLEVEL4_MASK \ - XCHAL_SEP XCHAL_INTLEVEL5_MASK \ - XCHAL_SEP XCHAL_INTLEVEL6_MASK \ - XCHAL_SEP XCHAL_INTLEVEL7_MASK \ - XCHAL_SEP XCHAL_INTLEVEL8_MASK \ - XCHAL_SEP XCHAL_INTLEVEL9_MASK \ - XCHAL_SEP XCHAL_INTLEVEL10_MASK \ - XCHAL_SEP XCHAL_INTLEVEL11_MASK \ - XCHAL_SEP XCHAL_INTLEVEL12_MASK \ - XCHAL_SEP XCHAL_INTLEVEL13_MASK \ - XCHAL_SEP XCHAL_INTLEVEL14_MASK \ - XCHAL_SEP XCHAL_INTLEVEL15_MASK - -/* These values are constant for existing Xtensa processor implementations: */ -#define XCHAL_INTLEVEL0_ANDBELOW_MASK 0x00000000 -#define XCHAL_INTLEVEL8_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK -#define XCHAL_INTLEVEL9_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK -#define XCHAL_INTLEVEL10_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK -#define XCHAL_INTLEVEL11_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK -#define XCHAL_INTLEVEL12_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK -#define XCHAL_INTLEVEL13_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK -#define XCHAL_INTLEVEL14_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK -#define XCHAL_INTLEVEL15_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK - -/* Mask of all low-priority interrupts: */ -#define XCHAL_LOWPRI_MASK XCHAL_INTLEVEL1_ANDBELOW_MASK - -/* Mask of all interrupts masked by PS.EXCM (or CEXCM): */ -#define XCHAL_EXCM_MASK XCHAL_INTLEVEL_ANDBELOW_MASK(XCHAL_EXCM_LEVEL) - -/* Array of masks of interrupts at each range 1..n of interrupt levels: */ -#define XCHAL_INTLEVEL_ANDBELOW_MASKS XCHAL_INTLEVEL0_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL1_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL2_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL3_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL4_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL5_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL6_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL7_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL8_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL9_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL10_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL11_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL12_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL13_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL14_ANDBELOW_MASK \ - XCHAL_SEP XCHAL_INTLEVEL15_ANDBELOW_MASK - -#if 0 /*XCHAL_HAVE_NMI*/ -/* NMI "interrupt level" (for use with EXCSAVE_n, EPS_n, EPC_n, RFI n): */ -# define XCHAL_NMILEVEL (XCHAL_NUM_INTLEVELS+1) -#endif - -/* Array of levels of each possible interrupt: */ -#define XCHAL_INT_LEVELS XCHAL_INT0_LEVEL \ - XCHAL_SEP XCHAL_INT1_LEVEL \ - XCHAL_SEP XCHAL_INT2_LEVEL \ - XCHAL_SEP XCHAL_INT3_LEVEL \ - XCHAL_SEP XCHAL_INT4_LEVEL \ - XCHAL_SEP XCHAL_INT5_LEVEL \ - XCHAL_SEP XCHAL_INT6_LEVEL \ - XCHAL_SEP XCHAL_INT7_LEVEL \ - XCHAL_SEP XCHAL_INT8_LEVEL \ - XCHAL_SEP XCHAL_INT9_LEVEL \ - XCHAL_SEP XCHAL_INT10_LEVEL \ - XCHAL_SEP XCHAL_INT11_LEVEL \ - XCHAL_SEP XCHAL_INT12_LEVEL \ - XCHAL_SEP XCHAL_INT13_LEVEL \ - XCHAL_SEP XCHAL_INT14_LEVEL \ - XCHAL_SEP XCHAL_INT15_LEVEL \ - XCHAL_SEP XCHAL_INT16_LEVEL \ - XCHAL_SEP XCHAL_INT17_LEVEL \ - XCHAL_SEP XCHAL_INT18_LEVEL \ - XCHAL_SEP XCHAL_INT19_LEVEL \ - XCHAL_SEP XCHAL_INT20_LEVEL \ - XCHAL_SEP XCHAL_INT21_LEVEL \ - XCHAL_SEP XCHAL_INT22_LEVEL \ - XCHAL_SEP XCHAL_INT23_LEVEL \ - XCHAL_SEP XCHAL_INT24_LEVEL \ - XCHAL_SEP XCHAL_INT25_LEVEL \ - XCHAL_SEP XCHAL_INT26_LEVEL \ - XCHAL_SEP XCHAL_INT27_LEVEL \ - XCHAL_SEP XCHAL_INT28_LEVEL \ - XCHAL_SEP XCHAL_INT29_LEVEL \ - XCHAL_SEP XCHAL_INT30_LEVEL \ - XCHAL_SEP XCHAL_INT31_LEVEL - -/* Array of types of each possible interrupt: */ -#define XCHAL_INT_TYPES XCHAL_INT0_TYPE \ - XCHAL_SEP XCHAL_INT1_TYPE \ - XCHAL_SEP XCHAL_INT2_TYPE \ - XCHAL_SEP XCHAL_INT3_TYPE \ - XCHAL_SEP XCHAL_INT4_TYPE \ - XCHAL_SEP XCHAL_INT5_TYPE \ - XCHAL_SEP XCHAL_INT6_TYPE \ - XCHAL_SEP XCHAL_INT7_TYPE \ - XCHAL_SEP XCHAL_INT8_TYPE \ - XCHAL_SEP XCHAL_INT9_TYPE \ - XCHAL_SEP XCHAL_INT10_TYPE \ - XCHAL_SEP XCHAL_INT11_TYPE \ - XCHAL_SEP XCHAL_INT12_TYPE \ - XCHAL_SEP XCHAL_INT13_TYPE \ - XCHAL_SEP XCHAL_INT14_TYPE \ - XCHAL_SEP XCHAL_INT15_TYPE \ - XCHAL_SEP XCHAL_INT16_TYPE \ - XCHAL_SEP XCHAL_INT17_TYPE \ - XCHAL_SEP XCHAL_INT18_TYPE \ - XCHAL_SEP XCHAL_INT19_TYPE \ - XCHAL_SEP XCHAL_INT20_TYPE \ - XCHAL_SEP XCHAL_INT21_TYPE \ - XCHAL_SEP XCHAL_INT22_TYPE \ - XCHAL_SEP XCHAL_INT23_TYPE \ - XCHAL_SEP XCHAL_INT24_TYPE \ - XCHAL_SEP XCHAL_INT25_TYPE \ - XCHAL_SEP XCHAL_INT26_TYPE \ - XCHAL_SEP XCHAL_INT27_TYPE \ - XCHAL_SEP XCHAL_INT28_TYPE \ - XCHAL_SEP XCHAL_INT29_TYPE \ - XCHAL_SEP XCHAL_INT30_TYPE \ - XCHAL_SEP XCHAL_INT31_TYPE - -/* Array of masks of interrupts for each type of interrupt: */ -#define XCHAL_INTTYPE_MASKS XCHAL_INTTYPE_MASK_UNCONFIGURED \ - XCHAL_SEP XCHAL_INTTYPE_MASK_SOFTWARE \ - XCHAL_SEP XCHAL_INTTYPE_MASK_EXTERN_EDGE \ - XCHAL_SEP XCHAL_INTTYPE_MASK_EXTERN_LEVEL \ - XCHAL_SEP XCHAL_INTTYPE_MASK_TIMER \ - XCHAL_SEP XCHAL_INTTYPE_MASK_NMI \ - XCHAL_SEP XCHAL_INTTYPE_MASK_WRITE_ERROR - -/* Interrupts that can be cleared using the INTCLEAR special register: */ -#define XCHAL_INTCLEARABLE_MASK (XCHAL_INTTYPE_MASK_SOFTWARE+XCHAL_INTTYPE_MASK_EXTERN_EDGE+XCHAL_INTTYPE_MASK_WRITE_ERROR) -/* Interrupts that can be triggered using the INTSET special register: */ -#define XCHAL_INTSETTABLE_MASK XCHAL_INTTYPE_MASK_SOFTWARE - -/* Array of interrupts assigned to each timer (CCOMPARE0 to CCOMPARE3): */ -#define XCHAL_TIMER_INTERRUPTS XCHAL_TIMER0_INTERRUPT \ - XCHAL_SEP XCHAL_TIMER1_INTERRUPT \ - XCHAL_SEP XCHAL_TIMER2_INTERRUPT \ - XCHAL_SEP XCHAL_TIMER3_INTERRUPT - - - -/* For backward compatibility and for the array macros, define macros for - * each unconfigured interrupt number (unfortunately, the value of - * XTHAL_INTTYPE_UNCONFIGURED is not zero): */ -#if XCHAL_NUM_INTERRUPTS == 0 -# define XCHAL_INT0_LEVEL 0 -# define XCHAL_INT0_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 1 -# define XCHAL_INT1_LEVEL 0 -# define XCHAL_INT1_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 2 -# define XCHAL_INT2_LEVEL 0 -# define XCHAL_INT2_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 3 -# define XCHAL_INT3_LEVEL 0 -# define XCHAL_INT3_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 4 -# define XCHAL_INT4_LEVEL 0 -# define XCHAL_INT4_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 5 -# define XCHAL_INT5_LEVEL 0 -# define XCHAL_INT5_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 6 -# define XCHAL_INT6_LEVEL 0 -# define XCHAL_INT6_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 7 -# define XCHAL_INT7_LEVEL 0 -# define XCHAL_INT7_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 8 -# define XCHAL_INT8_LEVEL 0 -# define XCHAL_INT8_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 9 -# define XCHAL_INT9_LEVEL 0 -# define XCHAL_INT9_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 10 -# define XCHAL_INT10_LEVEL 0 -# define XCHAL_INT10_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 11 -# define XCHAL_INT11_LEVEL 0 -# define XCHAL_INT11_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 12 -# define XCHAL_INT12_LEVEL 0 -# define XCHAL_INT12_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 13 -# define XCHAL_INT13_LEVEL 0 -# define XCHAL_INT13_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 14 -# define XCHAL_INT14_LEVEL 0 -# define XCHAL_INT14_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 15 -# define XCHAL_INT15_LEVEL 0 -# define XCHAL_INT15_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 16 -# define XCHAL_INT16_LEVEL 0 -# define XCHAL_INT16_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 17 -# define XCHAL_INT17_LEVEL 0 -# define XCHAL_INT17_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 18 -# define XCHAL_INT18_LEVEL 0 -# define XCHAL_INT18_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 19 -# define XCHAL_INT19_LEVEL 0 -# define XCHAL_INT19_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 20 -# define XCHAL_INT20_LEVEL 0 -# define XCHAL_INT20_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 21 -# define XCHAL_INT21_LEVEL 0 -# define XCHAL_INT21_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 22 -# define XCHAL_INT22_LEVEL 0 -# define XCHAL_INT22_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 23 -# define XCHAL_INT23_LEVEL 0 -# define XCHAL_INT23_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 24 -# define XCHAL_INT24_LEVEL 0 -# define XCHAL_INT24_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 25 -# define XCHAL_INT25_LEVEL 0 -# define XCHAL_INT25_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 26 -# define XCHAL_INT26_LEVEL 0 -# define XCHAL_INT26_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 27 -# define XCHAL_INT27_LEVEL 0 -# define XCHAL_INT27_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 28 -# define XCHAL_INT28_LEVEL 0 -# define XCHAL_INT28_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 29 -# define XCHAL_INT29_LEVEL 0 -# define XCHAL_INT29_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 30 -# define XCHAL_INT30_LEVEL 0 -# define XCHAL_INT30_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif -#if XCHAL_NUM_INTERRUPTS <= 31 -# define XCHAL_INT31_LEVEL 0 -# define XCHAL_INT31_TYPE XTHAL_INTTYPE_UNCONFIGURED -#endif - - -/* - * Masks and levels corresponding to each *external* interrupt. - */ - -#define XCHAL_EXTINT0_MASK (1 << XCHAL_EXTINT0_NUM) -#define XCHAL_EXTINT0_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT0_NUM) -#define XCHAL_EXTINT1_MASK (1 << XCHAL_EXTINT1_NUM) -#define XCHAL_EXTINT1_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT1_NUM) -#define XCHAL_EXTINT2_MASK (1 << XCHAL_EXTINT2_NUM) -#define XCHAL_EXTINT2_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT2_NUM) -#define XCHAL_EXTINT3_MASK (1 << XCHAL_EXTINT3_NUM) -#define XCHAL_EXTINT3_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT3_NUM) -#define XCHAL_EXTINT4_MASK (1 << XCHAL_EXTINT4_NUM) -#define XCHAL_EXTINT4_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT4_NUM) -#define XCHAL_EXTINT5_MASK (1 << XCHAL_EXTINT5_NUM) -#define XCHAL_EXTINT5_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT5_NUM) -#define XCHAL_EXTINT6_MASK (1 << XCHAL_EXTINT6_NUM) -#define XCHAL_EXTINT6_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT6_NUM) -#define XCHAL_EXTINT7_MASK (1 << XCHAL_EXTINT7_NUM) -#define XCHAL_EXTINT7_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT7_NUM) -#define XCHAL_EXTINT8_MASK (1 << XCHAL_EXTINT8_NUM) -#define XCHAL_EXTINT8_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT8_NUM) -#define XCHAL_EXTINT9_MASK (1 << XCHAL_EXTINT9_NUM) -#define XCHAL_EXTINT9_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT9_NUM) -#define XCHAL_EXTINT10_MASK (1 << XCHAL_EXTINT10_NUM) -#define XCHAL_EXTINT10_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT10_NUM) -#define XCHAL_EXTINT11_MASK (1 << XCHAL_EXTINT11_NUM) -#define XCHAL_EXTINT11_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT11_NUM) -#define XCHAL_EXTINT12_MASK (1 << XCHAL_EXTINT12_NUM) -#define XCHAL_EXTINT12_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT12_NUM) -#define XCHAL_EXTINT13_MASK (1 << XCHAL_EXTINT13_NUM) -#define XCHAL_EXTINT13_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT13_NUM) -#define XCHAL_EXTINT14_MASK (1 << XCHAL_EXTINT14_NUM) -#define XCHAL_EXTINT14_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT14_NUM) -#define XCHAL_EXTINT15_MASK (1 << XCHAL_EXTINT15_NUM) -#define XCHAL_EXTINT15_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT15_NUM) -#define XCHAL_EXTINT16_MASK (1 << XCHAL_EXTINT16_NUM) -#define XCHAL_EXTINT16_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT16_NUM) -#define XCHAL_EXTINT17_MASK (1 << XCHAL_EXTINT17_NUM) -#define XCHAL_EXTINT17_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT17_NUM) -#define XCHAL_EXTINT18_MASK (1 << XCHAL_EXTINT18_NUM) -#define XCHAL_EXTINT18_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT18_NUM) -#define XCHAL_EXTINT19_MASK (1 << XCHAL_EXTINT19_NUM) -#define XCHAL_EXTINT19_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT19_NUM) -#define XCHAL_EXTINT20_MASK (1 << XCHAL_EXTINT20_NUM) -#define XCHAL_EXTINT20_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT20_NUM) -#define XCHAL_EXTINT21_MASK (1 << XCHAL_EXTINT21_NUM) -#define XCHAL_EXTINT21_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT21_NUM) -#define XCHAL_EXTINT22_MASK (1 << XCHAL_EXTINT22_NUM) -#define XCHAL_EXTINT22_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT22_NUM) -#define XCHAL_EXTINT23_MASK (1 << XCHAL_EXTINT23_NUM) -#define XCHAL_EXTINT23_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT23_NUM) -#define XCHAL_EXTINT24_MASK (1 << XCHAL_EXTINT24_NUM) -#define XCHAL_EXTINT24_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT24_NUM) -#define XCHAL_EXTINT25_MASK (1 << XCHAL_EXTINT25_NUM) -#define XCHAL_EXTINT25_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT25_NUM) -#define XCHAL_EXTINT26_MASK (1 << XCHAL_EXTINT26_NUM) -#define XCHAL_EXTINT26_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT26_NUM) -#define XCHAL_EXTINT27_MASK (1 << XCHAL_EXTINT27_NUM) -#define XCHAL_EXTINT27_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT27_NUM) -#define XCHAL_EXTINT28_MASK (1 << XCHAL_EXTINT28_NUM) -#define XCHAL_EXTINT28_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT28_NUM) -#define XCHAL_EXTINT29_MASK (1 << XCHAL_EXTINT29_NUM) -#define XCHAL_EXTINT29_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT29_NUM) -#define XCHAL_EXTINT30_MASK (1 << XCHAL_EXTINT30_NUM) -#define XCHAL_EXTINT30_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT30_NUM) -#define XCHAL_EXTINT31_MASK (1 << XCHAL_EXTINT31_NUM) -#define XCHAL_EXTINT31_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT31_NUM) - - -/*---------------------------------------------------------------------- - EXCEPTIONS and VECTORS - ----------------------------------------------------------------------*/ - -/* For backward compatibility ONLY -- DO NOT USE (will be removed in future release): */ -#define XCHAL_HAVE_OLD_EXC_ARCH XCHAL_HAVE_XEA1 /* (DEPRECATED) 1 if old exception architecture (XEA1), 0 otherwise (eg. XEA2) */ -#define XCHAL_HAVE_EXCM XCHAL_HAVE_XEA2 /* (DEPRECATED) 1 if PS.EXCM bit exists (currently equals XCHAL_HAVE_TLBS) */ -#ifdef XCHAL_USER_VECTOR_VADDR -#define XCHAL_PROGRAMEXC_VECTOR_VADDR XCHAL_USER_VECTOR_VADDR -#define XCHAL_USEREXC_VECTOR_VADDR XCHAL_USER_VECTOR_VADDR -#endif -#ifdef XCHAL_USER_VECTOR_PADDR -# define XCHAL_PROGRAMEXC_VECTOR_PADDR XCHAL_USER_VECTOR_PADDR -# define XCHAL_USEREXC_VECTOR_PADDR XCHAL_USER_VECTOR_PADDR -#endif -#ifdef XCHAL_KERNEL_VECTOR_VADDR -# define XCHAL_STACKEDEXC_VECTOR_VADDR XCHAL_KERNEL_VECTOR_VADDR -# define XCHAL_KERNELEXC_VECTOR_VADDR XCHAL_KERNEL_VECTOR_VADDR -#endif -#ifdef XCHAL_KERNEL_VECTOR_PADDR -# define XCHAL_STACKEDEXC_VECTOR_PADDR XCHAL_KERNEL_VECTOR_PADDR -# define XCHAL_KERNELEXC_VECTOR_PADDR XCHAL_KERNEL_VECTOR_PADDR -#endif - -#if 0 -#if XCHAL_HAVE_DEBUG -# define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL_VECTOR_VADDR(XCHAL_DEBUGLEVEL) -/* This one should only get defined if the corresponding intlevel paddr macro exists: */ -# define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL_VECTOR_PADDR(XCHAL_DEBUGLEVEL) -#endif -#endif - -/* Indexing macros: */ -#define _XCHAL_INTLEVEL_VECTOR_VADDR(n) XCHAL_INTLEVEL ## n ## _VECTOR_VADDR -#define XCHAL_INTLEVEL_VECTOR_VADDR(n) _XCHAL_INTLEVEL_VECTOR_VADDR(n) /* n = 0 .. 15 */ - -/* - * General Exception Causes - * (values of EXCCAUSE special register set by general exceptions, - * which vector to the user, kernel, or double-exception vectors). - * - * DEPRECATED. Please use the equivalent EXCCAUSE_xxx macros - * defined in . (Note that these have slightly - * different names, they don't just have the XCHAL_ prefix removed.) - */ -#define XCHAL_EXCCAUSE_ILLEGAL_INSTRUCTION 0 /* Illegal Instruction */ -#define XCHAL_EXCCAUSE_SYSTEM_CALL 1 /* System Call */ -#define XCHAL_EXCCAUSE_INSTRUCTION_FETCH_ERROR 2 /* Instruction Fetch Error */ -#define XCHAL_EXCCAUSE_LOAD_STORE_ERROR 3 /* Load Store Error */ -#define XCHAL_EXCCAUSE_LEVEL1_INTERRUPT 4 /* Level 1 Interrupt */ -#define XCHAL_EXCCAUSE_ALLOCA 5 /* Stack Extension Assist */ -#define XCHAL_EXCCAUSE_INTEGER_DIVIDE_BY_ZERO 6 /* Integer Divide by Zero */ -#define XCHAL_EXCCAUSE_SPECULATION 7 /* Speculation */ -#define XCHAL_EXCCAUSE_PRIVILEGED 8 /* Privileged Instruction */ -#define XCHAL_EXCCAUSE_UNALIGNED 9 /* Unaligned Load Store */ -/*10..15 reserved*/ -#define XCHAL_EXCCAUSE_ITLB_MISS 16 /* ITlb Miss Exception */ -#define XCHAL_EXCCAUSE_ITLB_MULTIHIT 17 /* ITlb Mutltihit Exception */ -#define XCHAL_EXCCAUSE_ITLB_PRIVILEGE 18 /* ITlb Privilege Exception */ -#define XCHAL_EXCCAUSE_ITLB_SIZE_RESTRICTION 19 /* ITlb Size Restriction Exception */ -#define XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE 20 /* Fetch Cache Attribute Exception */ -/*21..23 reserved*/ -#define XCHAL_EXCCAUSE_DTLB_MISS 24 /* DTlb Miss Exception */ -#define XCHAL_EXCCAUSE_DTLB_MULTIHIT 25 /* DTlb Multihit Exception */ -#define XCHAL_EXCCAUSE_DTLB_PRIVILEGE 26 /* DTlb Privilege Exception */ -#define XCHAL_EXCCAUSE_DTLB_SIZE_RESTRICTION 27 /* DTlb Size Restriction Exception */ -#define XCHAL_EXCCAUSE_LOAD_CACHE_ATTRIBUTE 28 /* Load Cache Attribute Exception */ -#define XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE 29 /* Store Cache Attribute Exception */ -/*30..31 reserved*/ -#define XCHAL_EXCCAUSE_COPROCESSOR0_DISABLED 32 /* Coprocessor 0 disabled */ -#define XCHAL_EXCCAUSE_COPROCESSOR1_DISABLED 33 /* Coprocessor 1 disabled */ -#define XCHAL_EXCCAUSE_COPROCESSOR2_DISABLED 34 /* Coprocessor 2 disabled */ -#define XCHAL_EXCCAUSE_COPROCESSOR3_DISABLED 35 /* Coprocessor 3 disabled */ -#define XCHAL_EXCCAUSE_COPROCESSOR4_DISABLED 36 /* Coprocessor 4 disabled */ -#define XCHAL_EXCCAUSE_COPROCESSOR5_DISABLED 37 /* Coprocessor 5 disabled */ -#define XCHAL_EXCCAUSE_COPROCESSOR6_DISABLED 38 /* Coprocessor 6 disabled */ -#define XCHAL_EXCCAUSE_COPROCESSOR7_DISABLED 39 /* Coprocessor 7 disabled */ -#define XCHAL_EXCCAUSE_FLOATING_POINT 40 /* Floating Point Exception */ -/*40..63 reserved*/ - - -/* - * Miscellaneous special register fields. - * - * For each special register, and each field within each register: - * XCHAL__VALIDMASK is the set of bits defined in the register. - * XCHAL___BITS is the number of bits in the field. - * XCHAL___NUM is 2^bits, the number of possible values - * of the field. - * XCHAL___SHIFT is the position of the field within - * the register, starting from the least significant bit. - * - * DEPRECATED. Please use the equivalent macros defined in - * . (Note that these have different names.) - */ - -/* DBREAKC (special register number 160): */ -#define XCHAL_DBREAKC_VALIDMASK 0xC000003F -#define XCHAL_DBREAKC_MASK_BITS 6 -#define XCHAL_DBREAKC_MASK_NUM 64 -#define XCHAL_DBREAKC_MASK_SHIFT 0 -#define XCHAL_DBREAKC_MASK_MASK 0x0000003F -#define XCHAL_DBREAKC_LOADBREAK_BITS 1 -#define XCHAL_DBREAKC_LOADBREAK_NUM 2 -#define XCHAL_DBREAKC_LOADBREAK_SHIFT 30 -#define XCHAL_DBREAKC_LOADBREAK_MASK 0x40000000 -#define XCHAL_DBREAKC_STOREBREAK_BITS 1 -#define XCHAL_DBREAKC_STOREBREAK_NUM 2 -#define XCHAL_DBREAKC_STOREBREAK_SHIFT 31 -#define XCHAL_DBREAKC_STOREBREAK_MASK 0x80000000 -/* PS (special register number 230): */ -#define XCHAL_PS_VALIDMASK 0x00070F3F -#define XCHAL_PS_INTLEVEL_BITS 4 -#define XCHAL_PS_INTLEVEL_NUM 16 -#define XCHAL_PS_INTLEVEL_SHIFT 0 -#define XCHAL_PS_INTLEVEL_MASK 0x0000000F -#define XCHAL_PS_EXCM_BITS 1 -#define XCHAL_PS_EXCM_NUM 2 -#define XCHAL_PS_EXCM_SHIFT 4 -#define XCHAL_PS_EXCM_MASK 0x00000010 -#define XCHAL_PS_UM_BITS 1 -#define XCHAL_PS_UM_NUM 2 -#define XCHAL_PS_UM_SHIFT 5 -#define XCHAL_PS_UM_MASK 0x00000020 -#define XCHAL_PS_RING_BITS 2 -#define XCHAL_PS_RING_NUM 4 -#define XCHAL_PS_RING_SHIFT 6 -#define XCHAL_PS_RING_MASK 0x000000C0 -#define XCHAL_PS_OWB_BITS 4 -#define XCHAL_PS_OWB_NUM 16 -#define XCHAL_PS_OWB_SHIFT 8 -#define XCHAL_PS_OWB_MASK 0x00000F00 -#define XCHAL_PS_CALLINC_BITS 2 -#define XCHAL_PS_CALLINC_NUM 4 -#define XCHAL_PS_CALLINC_SHIFT 16 -#define XCHAL_PS_CALLINC_MASK 0x00030000 -#define XCHAL_PS_WOE_BITS 1 -#define XCHAL_PS_WOE_NUM 2 -#define XCHAL_PS_WOE_SHIFT 18 -#define XCHAL_PS_WOE_MASK 0x00040000 -/* EXCCAUSE (special register number 232): */ -#define XCHAL_EXCCAUSE_VALIDMASK 0x0000003F -#define XCHAL_EXCCAUSE_BITS 6 -#define XCHAL_EXCCAUSE_NUM 64 -#define XCHAL_EXCCAUSE_SHIFT 0 -#define XCHAL_EXCCAUSE_MASK 0x0000003F -/* DEBUGCAUSE (special register number 233): */ -#define XCHAL_DEBUGCAUSE_VALIDMASK 0x0000003F -#define XCHAL_DEBUGCAUSE_ICOUNT_BITS 1 -#define XCHAL_DEBUGCAUSE_ICOUNT_NUM 2 -#define XCHAL_DEBUGCAUSE_ICOUNT_SHIFT 0 -#define XCHAL_DEBUGCAUSE_ICOUNT_MASK 0x00000001 -#define XCHAL_DEBUGCAUSE_IBREAK_BITS 1 -#define XCHAL_DEBUGCAUSE_IBREAK_NUM 2 -#define XCHAL_DEBUGCAUSE_IBREAK_SHIFT 1 -#define XCHAL_DEBUGCAUSE_IBREAK_MASK 0x00000002 -#define XCHAL_DEBUGCAUSE_DBREAK_BITS 1 -#define XCHAL_DEBUGCAUSE_DBREAK_NUM 2 -#define XCHAL_DEBUGCAUSE_DBREAK_SHIFT 2 -#define XCHAL_DEBUGCAUSE_DBREAK_MASK 0x00000004 -#define XCHAL_DEBUGCAUSE_BREAK_BITS 1 -#define XCHAL_DEBUGCAUSE_BREAK_NUM 2 -#define XCHAL_DEBUGCAUSE_BREAK_SHIFT 3 -#define XCHAL_DEBUGCAUSE_BREAK_MASK 0x00000008 -#define XCHAL_DEBUGCAUSE_BREAKN_BITS 1 -#define XCHAL_DEBUGCAUSE_BREAKN_NUM 2 -#define XCHAL_DEBUGCAUSE_BREAKN_SHIFT 4 -#define XCHAL_DEBUGCAUSE_BREAKN_MASK 0x00000010 -#define XCHAL_DEBUGCAUSE_DEBUGINT_BITS 1 -#define XCHAL_DEBUGCAUSE_DEBUGINT_NUM 2 -#define XCHAL_DEBUGCAUSE_DEBUGINT_SHIFT 5 -#define XCHAL_DEBUGCAUSE_DEBUGINT_MASK 0x00000020 - - - - -/*---------------------------------------------------------------------- - TIMERS - ----------------------------------------------------------------------*/ - -/*#define XCHAL_HAVE_TIMERS XCHAL_HAVE_CCOUNT*/ - - - -/*---------------------------------------------------------------------- - INTERNAL I/D RAM/ROMs and XLMI - ----------------------------------------------------------------------*/ - -#define XCHAL_NUM_IROM XCHAL_NUM_INSTROM /* (DEPRECATED) */ -#define XCHAL_NUM_IRAM XCHAL_NUM_INSTRAM /* (DEPRECATED) */ -#define XCHAL_NUM_DROM XCHAL_NUM_DATAROM /* (DEPRECATED) */ -#define XCHAL_NUM_DRAM XCHAL_NUM_DATARAM /* (DEPRECATED) */ - -#define XCHAL_IROM0_VADDR XCHAL_INSTROM0_VADDR /* (DEPRECATED) */ -#define XCHAL_IROM0_PADDR XCHAL_INSTROM0_PADDR /* (DEPRECATED) */ -#define XCHAL_IROM0_SIZE XCHAL_INSTROM0_SIZE /* (DEPRECATED) */ -#define XCHAL_IROM1_VADDR XCHAL_INSTROM1_VADDR /* (DEPRECATED) */ -#define XCHAL_IROM1_PADDR XCHAL_INSTROM1_PADDR /* (DEPRECATED) */ -#define XCHAL_IROM1_SIZE XCHAL_INSTROM1_SIZE /* (DEPRECATED) */ -#define XCHAL_IRAM0_VADDR XCHAL_INSTRAM0_VADDR /* (DEPRECATED) */ -#define XCHAL_IRAM0_PADDR XCHAL_INSTRAM0_PADDR /* (DEPRECATED) */ -#define XCHAL_IRAM0_SIZE XCHAL_INSTRAM0_SIZE /* (DEPRECATED) */ -#define XCHAL_IRAM1_VADDR XCHAL_INSTRAM1_VADDR /* (DEPRECATED) */ -#define XCHAL_IRAM1_PADDR XCHAL_INSTRAM1_PADDR /* (DEPRECATED) */ -#define XCHAL_IRAM1_SIZE XCHAL_INSTRAM1_SIZE /* (DEPRECATED) */ -#define XCHAL_DROM0_VADDR XCHAL_DATAROM0_VADDR /* (DEPRECATED) */ -#define XCHAL_DROM0_PADDR XCHAL_DATAROM0_PADDR /* (DEPRECATED) */ -#define XCHAL_DROM0_SIZE XCHAL_DATAROM0_SIZE /* (DEPRECATED) */ -#define XCHAL_DROM1_VADDR XCHAL_DATAROM1_VADDR /* (DEPRECATED) */ -#define XCHAL_DROM1_PADDR XCHAL_DATAROM1_PADDR /* (DEPRECATED) */ -#define XCHAL_DROM1_SIZE XCHAL_DATAROM1_SIZE /* (DEPRECATED) */ -#define XCHAL_DRAM0_VADDR XCHAL_DATARAM0_VADDR /* (DEPRECATED) */ -#define XCHAL_DRAM0_PADDR XCHAL_DATARAM0_PADDR /* (DEPRECATED) */ -#define XCHAL_DRAM0_SIZE XCHAL_DATARAM0_SIZE /* (DEPRECATED) */ -#define XCHAL_DRAM1_VADDR XCHAL_DATARAM1_VADDR /* (DEPRECATED) */ -#define XCHAL_DRAM1_PADDR XCHAL_DATARAM1_PADDR /* (DEPRECATED) */ -#define XCHAL_DRAM1_SIZE XCHAL_DATARAM1_SIZE /* (DEPRECATED) */ - - - -/*---------------------------------------------------------------------- - CACHE - ----------------------------------------------------------------------*/ - - -/* Default PREFCTL value to enable prefetch. */ -#define XCHAL_CACHE_PREFCTL_DEFAULT 0x44 - - -/* Max for both I-cache and D-cache (used for general alignment): */ -#if XCHAL_ICACHE_LINESIZE > XCHAL_DCACHE_LINESIZE -# define XCHAL_CACHE_LINEWIDTH_MAX XCHAL_ICACHE_LINEWIDTH -# define XCHAL_CACHE_LINESIZE_MAX XCHAL_ICACHE_LINESIZE -#else -# define XCHAL_CACHE_LINEWIDTH_MAX XCHAL_DCACHE_LINEWIDTH -# define XCHAL_CACHE_LINESIZE_MAX XCHAL_DCACHE_LINESIZE -#endif - -#define XCHAL_ICACHE_SETSIZE (1< XCHAL_DCACHE_SETWIDTH -# define XCHAL_CACHE_SETWIDTH_MAX XCHAL_ICACHE_SETWIDTH -# define XCHAL_CACHE_SETSIZE_MAX XCHAL_ICACHE_SETSIZE -#else -# define XCHAL_CACHE_SETWIDTH_MAX XCHAL_DCACHE_SETWIDTH -# define XCHAL_CACHE_SETSIZE_MAX XCHAL_DCACHE_SETSIZE -#endif - -/* Instruction cache tag bits: */ -#define XCHAL_ICACHE_TAG_V_SHIFT 0 -#define XCHAL_ICACHE_TAG_V 0x1 /* valid bit */ -#if XCHAL_ICACHE_WAYS > 1 -# define XCHAL_ICACHE_TAG_F_SHIFT 1 -# define XCHAL_ICACHE_TAG_F 0x2 /* fill (LRU) bit */ -#else -# define XCHAL_ICACHE_TAG_F_SHIFT 0 -# define XCHAL_ICACHE_TAG_F 0 /* no fill (LRU) bit */ -#endif -#if XCHAL_ICACHE_LINE_LOCKABLE -# define XCHAL_ICACHE_TAG_L_SHIFT (XCHAL_ICACHE_TAG_F_SHIFT+1) -# define XCHAL_ICACHE_TAG_L (1 << XCHAL_ICACHE_TAG_L_SHIFT) /* lock bit */ -#else -# define XCHAL_ICACHE_TAG_L_SHIFT XCHAL_ICACHE_TAG_F_SHIFT -# define XCHAL_ICACHE_TAG_L 0 /* no lock bit */ -#endif -/* Data cache tag bits: */ -#define XCHAL_DCACHE_TAG_V_SHIFT 0 -#define XCHAL_DCACHE_TAG_V 0x1 /* valid bit */ -#if XCHAL_DCACHE_WAYS > 1 -# define XCHAL_DCACHE_TAG_F_SHIFT 1 -# define XCHAL_DCACHE_TAG_F 0x2 /* fill (LRU) bit */ -#else -# define XCHAL_DCACHE_TAG_F_SHIFT 0 -# define XCHAL_DCACHE_TAG_F 0 /* no fill (LRU) bit */ -#endif -#if XCHAL_DCACHE_IS_WRITEBACK -# define XCHAL_DCACHE_TAG_D_SHIFT (XCHAL_DCACHE_TAG_F_SHIFT+1) -# define XCHAL_DCACHE_TAG_D (1 << XCHAL_DCACHE_TAG_D_SHIFT) /* dirty bit */ -#else -# define XCHAL_DCACHE_TAG_D_SHIFT XCHAL_DCACHE_TAG_F_SHIFT -# define XCHAL_DCACHE_TAG_D 0 /* no dirty bit */ -#endif -#if XCHAL_DCACHE_LINE_LOCKABLE -# define XCHAL_DCACHE_TAG_L_SHIFT (XCHAL_DCACHE_TAG_D_SHIFT+1) -# define XCHAL_DCACHE_TAG_L (1 << XCHAL_DCACHE_TAG_D_SHIFT) /* lock bit */ -#else -# define XCHAL_DCACHE_TAG_L_SHIFT XCHAL_DCACHE_TAG_D_SHIFT -# define XCHAL_DCACHE_TAG_L 0 /* no lock bit */ -#endif - - -/*---------------------------------------------------------------------- - MMU - ----------------------------------------------------------------------*/ - -/* See for more details. */ - -/* Has different semantic in open source headers (where it means HAVE_PTP_MMU), - so comment out starting with RB-2008.3 release; later, might get - get reintroduced as a synonym for XCHAL_HAVE_PTP_MMU instead: */ -/*#define XCHAL_HAVE_MMU XCHAL_HAVE_TLBS*/ /* (DEPRECATED; use XCHAL_HAVE_TLBS instead) */ - -/* Indexing macros: */ -#define _XCHAL_ITLB_SET(n,_what) XCHAL_ITLB_SET ## n ## _what -#define XCHAL_ITLB_SET(n,what) _XCHAL_ITLB_SET(n, _ ## what ) -#define _XCHAL_ITLB_SET_E(n,i,_what) XCHAL_ITLB_SET ## n ## _E ## i ## _what -#define XCHAL_ITLB_SET_E(n,i,what) _XCHAL_ITLB_SET_E(n,i, _ ## what ) -#define _XCHAL_DTLB_SET(n,_what) XCHAL_DTLB_SET ## n ## _what -#define XCHAL_DTLB_SET(n,what) _XCHAL_DTLB_SET(n, _ ## what ) -#define _XCHAL_DTLB_SET_E(n,i,_what) XCHAL_DTLB_SET ## n ## _E ## i ## _what -#define XCHAL_DTLB_SET_E(n,i,what) _XCHAL_DTLB_SET_E(n,i, _ ## what ) -/* - * Example use: XCHAL_ITLB_SET(XCHAL_ITLB_ARF_SET0,ENTRIES) - * to get the value of XCHAL_ITLB_SET_ENTRIES where is the first auto-refill set. - */ - -/* Number of entries per autorefill way: */ -#define XCHAL_ITLB_ARF_ENTRIES (1< 0 && XCHAL_DTLB_ARF_WAYS > 0 && XCHAL_MMU_RINGS >= 2 -# define XCHAL_HAVE_PTP_MMU 1 /* have full MMU (with page table [autorefill] and protection) */ -#else -# define XCHAL_HAVE_PTP_MMU 0 /* don't have full MMU */ -#endif -#endif - -/* - * For full MMUs, report kernel RAM segment and kernel I/O segment static page mappings: - */ -#if XCHAL_HAVE_PTP_MMU && !XCHAL_HAVE_SPANNING_WAY -#define XCHAL_KSEG_CACHED_VADDR 0xD0000000 /* virt.addr of kernel RAM cached static map */ -#define XCHAL_KSEG_CACHED_PADDR 0x00000000 /* phys.addr of kseg_cached */ -#define XCHAL_KSEG_CACHED_SIZE 0x08000000 /* size in bytes of kseg_cached (assumed power of 2!!!) */ -#define XCHAL_KSEG_BYPASS_VADDR 0xD8000000 /* virt.addr of kernel RAM bypass (uncached) static map */ -#define XCHAL_KSEG_BYPASS_PADDR 0x00000000 /* phys.addr of kseg_bypass */ -#define XCHAL_KSEG_BYPASS_SIZE 0x08000000 /* size in bytes of kseg_bypass (assumed power of 2!!!) */ - -#define XCHAL_KIO_CACHED_VADDR 0xE0000000 /* virt.addr of kernel I/O cached static map */ -#define XCHAL_KIO_CACHED_PADDR 0xF0000000 /* phys.addr of kio_cached */ -#define XCHAL_KIO_CACHED_SIZE 0x10000000 /* size in bytes of kio_cached (assumed power of 2!!!) */ -#define XCHAL_KIO_BYPASS_VADDR 0xF0000000 /* virt.addr of kernel I/O bypass (uncached) static map */ -#define XCHAL_KIO_BYPASS_PADDR 0xF0000000 /* phys.addr of kio_bypass */ -#define XCHAL_KIO_BYPASS_SIZE 0x10000000 /* size in bytes of kio_bypass (assumed power of 2!!!) */ - -#define XCHAL_SEG_MAPPABLE_VADDR 0x00000000 /* start of largest non-static-mapped virtual addr area */ -#define XCHAL_SEG_MAPPABLE_SIZE 0xD0000000 /* size in bytes of " */ -/* define XCHAL_SEG_MAPPABLE2_xxx if more areas present, sorted in order of descending size. */ -#endif - - -/*---------------------------------------------------------------------- - MISC - ----------------------------------------------------------------------*/ - -/* Data alignment required if used for instructions: */ -#if XCHAL_INST_FETCH_WIDTH > XCHAL_DATA_WIDTH -# define XCHAL_ALIGN_MAX XCHAL_INST_FETCH_WIDTH -#else -# define XCHAL_ALIGN_MAX XCHAL_DATA_WIDTH -#endif - -/* - * Names kept for backward compatibility. - * (Here "RELEASE" is now a misnomer; these are product *versions*, not the releases - * under which they are released. In the T10##.# era there was no distinction.) - */ -#define XCHAL_HW_RELEASE_MAJOR XCHAL_HW_VERSION_MAJOR -#define XCHAL_HW_RELEASE_MINOR XCHAL_HW_VERSION_MINOR -#define XCHAL_HW_RELEASE_NAME XCHAL_HW_VERSION_NAME - - - - -/*---------------------------------------------------------------------- - COPROCESSORS and EXTRA STATE - ----------------------------------------------------------------------*/ - -#define XCHAL_EXTRA_SA_SIZE XCHAL_NCP_SA_SIZE -#define XCHAL_EXTRA_SA_ALIGN XCHAL_NCP_SA_ALIGN -#define XCHAL_CPEXTRA_SA_SIZE XCHAL_TOTAL_SA_SIZE -#define XCHAL_CPEXTRA_SA_ALIGN XCHAL_TOTAL_SA_ALIGN - -#if defined (_ASMLANGUAGE) || defined (__ASSEMBLER__) - - /* Invoked at start of save area load/store sequence macro to setup macro - * internal offsets. Not usually invoked directly. - * continue 0 for 1st sequence, 1 for subsequent consecutive ones. - * totofs offset from original ptr to next load/store location. - */ - .macro xchal_sa_start continue totofs - .ifeq \continue - .set .Lxchal_pofs_, 0 /* offset from original ptr to current \ptr */ - .set .Lxchal_ofs_, 0 /* offset from current \ptr to next load/store location */ - .endif - .if \totofs + 1 /* if totofs specified (not -1) */ - .set .Lxchal_ofs_, \totofs - .Lxchal_pofs_ /* specific offset from original ptr */ - .endif - .endm - - /* Align portion of save area and bring ptr in range if necessary. - * Used by save area load/store sequences. Not usually invoked directly. - * Allows combining multiple (sub-)sequences arbitrarily. - * ptr pointer to save area (may be off, see .Lxchal_pofs_) - * minofs,maxofs range of offset from cur ptr to next load/store loc; - * minofs <= 0 <= maxofs (0 must always be valid offset) - * range must be within +/- 30kB or so. - * ofsalign alignment granularity of minofs .. maxofs (pow of 2) - * (restriction on offset from ptr to next load/store loc) - * totalign align from orig ptr to next load/store loc (pow of 2) - */ - .macro xchal_sa_align ptr minofs maxofs ofsalign totalign - .set .Lxchal_ofs_, ((.Lxchal_pofs_ + .Lxchal_ofs_ + \totalign - 1) & -\totalign) - .Lxchal_pofs_ - /* If necessary, adjust \ptr to bring .Lxchal_ofs_ in acceptable range: */ - .if (((\maxofs) - .Lxchal_ofs_) & 0xC0000000) | ((.Lxchal_ofs_ - (\minofs)) & 0xC0000000) | (.Lxchal_ofs_ & (\ofsalign-1)) - .set .Ligmask, 0xFFFFFFFF /* TODO: optimize to addmi, per aligns and .Lxchal_ofs_ */ - addi \ptr, \ptr, (.Lxchal_ofs_ & .Ligmask) - .set .Lxchal_pofs_, .Lxchal_pofs_ + (.Lxchal_ofs_ & .Ligmask) - .set .Lxchal_ofs_, (.Lxchal_ofs_ & ~.Ligmask) - .endif - .endm - /* - * We could optimize for addi to expand to only addmi instead of - * "addmi;addi", where possible. Here's a partial example how: - * .set .Lmaxmask, -(\ofsalign) & -(\totalign) - * .if (((\maxofs) + ~.Lmaxmask + 1) & 0xFFFFFF00) && ((.Lxchal_ofs_ & ~.Lmaxmask) == 0) - * .set .Ligmask, 0xFFFFFF00 - * .elif ... ditto for negative ofs range ... - * .set .Ligmask, 0xFFFFFF00 - * .set ... adjust per offset ... - * .else - * .set .Ligmask, 0xFFFFFFFF - * .endif - */ - - /* Invoke this after xchal_XXX_{load,store} macros to restore \ptr. */ - .macro xchal_sa_ptr_restore ptr - .if .Lxchal_pofs_ - addi \ptr, \ptr, - .Lxchal_pofs_ - .set .Lxchal_ofs_, .Lxchal_ofs_ + .Lxchal_pofs_ - .set .Lxchal_pofs_, 0 - .endif - .endm - - /* - * Use as eg: - * xchal_atmps_store a1, SOMEOFS, XCHAL_SA_NUM_ATMPS, a4, a5 - * xchal_ncp_load a2, a0,a3,a4,a5 - * xchal_atmps_load a1, SOMEOFS, XCHAL_SA_NUM_ATMPS, a4, a5 - * - * Specify only the ARs you *haven't* saved/restored already, up to 4. - * They *must* be the *last* ARs (in same order) specified to save area - * load/store sequences. In the example above, a0 and a3 were already - * saved/restored and unused (thus available) but a4 and a5 were not. - */ -#define xchal_atmps_store xchal_atmps_loadstore s32i, -#define xchal_atmps_load xchal_atmps_loadstore l32i, - .macro xchal_atmps_loadstore inst ptr offset nreq aa=0 ab=0 ac=0 ad=0 - .set .Lnsaved_, 0 - .irp reg,\aa,\ab,\ac,\ad - .ifeq 0x\reg ; .set .Lnsaved_,.Lnsaved_+1 ; .endif - .endr - .set .Laofs_, 0 - .irp reg,\aa,\ab,\ac,\ad - .ifgt (\nreq)-.Lnsaved_ - \inst \reg, \ptr, .Laofs_+\offset - .set .Laofs_,.Laofs_+4 - .set .Lnsaved_,.Lnsaved_+1 - .endif - .endr - .endm - -/*#define xchal_ncp_load_a2 xchal_ncp_load a2,a3,a4,a5,a6*/ -/*#define xchal_ncp_store_a2 xchal_ncp_store a2,a3,a4,a5,a6*/ -#define xchal_extratie_load xchal_ncptie_load -#define xchal_extratie_store xchal_ncptie_store -#define xchal_extratie_load_a2 xchal_ncptie_load a2,a3,a4,a5,a6 -#define xchal_extratie_store_a2 xchal_ncptie_store a2,a3,a4,a5,a6 -#define xchal_extra_load xchal_ncp_load -#define xchal_extra_store xchal_ncp_store -#define xchal_extra_load_a2 xchal_ncp_load a2,a3,a4,a5,a6 -#define xchal_extra_store_a2 xchal_ncp_store a2,a3,a4,a5,a6 -#define xchal_extra_load_funcbody xchal_ncp_load a2,a3,a4,a5,a6 -#define xchal_extra_store_funcbody xchal_ncp_store a2,a3,a4,a5,a6 -#define xchal_cp0_store_a2 xchal_cp0_store a2,a3,a4,a5,a6 -#define xchal_cp0_load_a2 xchal_cp0_load a2,a3,a4,a5,a6 -#define xchal_cp1_store_a2 xchal_cp1_store a2,a3,a4,a5,a6 -#define xchal_cp1_load_a2 xchal_cp1_load a2,a3,a4,a5,a6 -#define xchal_cp2_store_a2 xchal_cp2_store a2,a3,a4,a5,a6 -#define xchal_cp2_load_a2 xchal_cp2_load a2,a3,a4,a5,a6 -#define xchal_cp3_store_a2 xchal_cp3_store a2,a3,a4,a5,a6 -#define xchal_cp3_load_a2 xchal_cp3_load a2,a3,a4,a5,a6 -#define xchal_cp4_store_a2 xchal_cp4_store a2,a3,a4,a5,a6 -#define xchal_cp4_load_a2 xchal_cp4_load a2,a3,a4,a5,a6 -#define xchal_cp5_store_a2 xchal_cp5_store a2,a3,a4,a5,a6 -#define xchal_cp5_load_a2 xchal_cp5_load a2,a3,a4,a5,a6 -#define xchal_cp6_store_a2 xchal_cp6_store a2,a3,a4,a5,a6 -#define xchal_cp6_load_a2 xchal_cp6_load a2,a3,a4,a5,a6 -#define xchal_cp7_store_a2 xchal_cp7_store a2,a3,a4,a5,a6 -#define xchal_cp7_load_a2 xchal_cp7_load a2,a3,a4,a5,a6 - -/* Empty placeholder macros for undefined coprocessors: */ -#if (XCHAL_CP_MASK & ~XCHAL_CP_PORT_MASK) == 0 -# if XCHAL_CP0_SA_SIZE == 0 - .macro xchal_cp0_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp0_load p a b c d continue=0 ofs=-1 select=-1 ; .endm -# endif -# if XCHAL_CP1_SA_SIZE == 0 - .macro xchal_cp1_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp1_load p a b c d continue=0 ofs=-1 select=-1 ; .endm -# endif -# if XCHAL_CP2_SA_SIZE == 0 - .macro xchal_cp2_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp2_load p a b c d continue=0 ofs=-1 select=-1 ; .endm -# endif -# if XCHAL_CP3_SA_SIZE == 0 - .macro xchal_cp3_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp3_load p a b c d continue=0 ofs=-1 select=-1 ; .endm -# endif -# if XCHAL_CP4_SA_SIZE == 0 - .macro xchal_cp4_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp4_load p a b c d continue=0 ofs=-1 select=-1 ; .endm -# endif -# if XCHAL_CP5_SA_SIZE == 0 - .macro xchal_cp5_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp5_load p a b c d continue=0 ofs=-1 select=-1 ; .endm -# endif -# if XCHAL_CP6_SA_SIZE == 0 - .macro xchal_cp6_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp6_load p a b c d continue=0 ofs=-1 select=-1 ; .endm -# endif -# if XCHAL_CP7_SA_SIZE == 0 - .macro xchal_cp7_store p a b c d continue=0 ofs=-1 select=-1 ; .endm - .macro xchal_cp7_load p a b c d continue=0 ofs=-1 select=-1 ; .endm -# endif -#endif - - /******************** - * Macros to create functions that save and restore the state of *any* TIE - * coprocessor (by dynamic index). - */ - - /* - * Macro that expands to the body of a function - * that stores the selected coprocessor's state (registers etc). - * Entry: a2 = ptr to save area in which to save cp state - * a3 = coprocessor number - * Exit: any register a2-a15 (?) may have been clobbered. - */ - .macro xchal_cpi_store_funcbody -#if (XCHAL_CP_MASK & ~XCHAL_CP_PORT_MASK) -# if XCHAL_CP0_SA_SIZE - bnez a3, 99f - xchal_cp0_store_a2 - j 90f -99: -# endif -# if XCHAL_CP1_SA_SIZE - bnei a3, 1, 99f - xchal_cp1_store_a2 - j 90f -99: -# endif -# if XCHAL_CP2_SA_SIZE - bnei a3, 2, 99f - xchal_cp2_store_a2 - j 90f -99: -# endif -# if XCHAL_CP3_SA_SIZE - bnei a3, 3, 99f - xchal_cp3_store_a2 - j 90f -99: -# endif -# if XCHAL_CP4_SA_SIZE - bnei a3, 4, 99f - xchal_cp4_store_a2 - j 90f -99: -# endif -# if XCHAL_CP5_SA_SIZE - bnei a3, 5, 99f - xchal_cp5_store_a2 - j 90f -99: -# endif -# if XCHAL_CP6_SA_SIZE - bnei a3, 6, 99f - xchal_cp6_store_a2 - j 90f -99: -# endif -# if XCHAL_CP7_SA_SIZE - bnei a3, 7, 99f - xchal_cp7_store_a2 - j 90f -99: -# endif -90: -#endif - .endm - - /* - * Macro that expands to the body of a function - * that loads the selected coprocessor's state (registers etc). - * Entry: a2 = ptr to save area from which to restore cp state - * a3 = coprocessor number - * Exit: any register a2-a15 (?) may have been clobbered. - */ - .macro xchal_cpi_load_funcbody -#if (XCHAL_CP_MASK & ~XCHAL_CP_PORT_MASK) -# if XCHAL_CP0_SA_SIZE - bnez a3, 99f - xchal_cp0_load_a2 - j 90f -99: -# endif -# if XCHAL_CP1_SA_SIZE - bnei a3, 1, 99f - xchal_cp1_load_a2 - j 90f -99: -# endif -# if XCHAL_CP2_SA_SIZE - bnei a3, 2, 99f - xchal_cp2_load_a2 - j 90f -99: -# endif -# if XCHAL_CP3_SA_SIZE - bnei a3, 3, 99f - xchal_cp3_load_a2 - j 90f -99: -# endif -# if XCHAL_CP4_SA_SIZE - bnei a3, 4, 99f - xchal_cp4_load_a2 - j 90f -99: -# endif -# if XCHAL_CP5_SA_SIZE - bnei a3, 5, 99f - xchal_cp5_load_a2 - j 90f -99: -# endif -# if XCHAL_CP6_SA_SIZE - bnei a3, 6, 99f - xchal_cp6_load_a2 - j 90f -99: -# endif -# if XCHAL_CP7_SA_SIZE - bnei a3, 7, 99f - xchal_cp7_load_a2 - j 90f -99: -# endif -90: -#endif - .endm - -#endif /*_ASMLANGUAGE or __ASSEMBLER__*/ - - -/* Other default macros for undefined coprocessors: */ -#ifndef XCHAL_CP0_NAME -# define XCHAL_CP0_NAME 0 -# define XCHAL_CP0_SA_CONTENTS_LIBDB_NUM 0 -# define XCHAL_CP0_SA_CONTENTS_LIBDB /* empty */ -#endif -#ifndef XCHAL_CP1_NAME -# define XCHAL_CP1_NAME 0 -# define XCHAL_CP1_SA_CONTENTS_LIBDB_NUM 0 -# define XCHAL_CP1_SA_CONTENTS_LIBDB /* empty */ -#endif -#ifndef XCHAL_CP2_NAME -# define XCHAL_CP2_NAME 0 -# define XCHAL_CP2_SA_CONTENTS_LIBDB_NUM 0 -# define XCHAL_CP2_SA_CONTENTS_LIBDB /* empty */ -#endif -#ifndef XCHAL_CP3_NAME -# define XCHAL_CP3_NAME 0 -# define XCHAL_CP3_SA_CONTENTS_LIBDB_NUM 0 -# define XCHAL_CP3_SA_CONTENTS_LIBDB /* empty */ -#endif -#ifndef XCHAL_CP4_NAME -# define XCHAL_CP4_NAME 0 -# define XCHAL_CP4_SA_CONTENTS_LIBDB_NUM 0 -# define XCHAL_CP4_SA_CONTENTS_LIBDB /* empty */ -#endif -#ifndef XCHAL_CP5_NAME -# define XCHAL_CP5_NAME 0 -# define XCHAL_CP5_SA_CONTENTS_LIBDB_NUM 0 -# define XCHAL_CP5_SA_CONTENTS_LIBDB /* empty */ -#endif -#ifndef XCHAL_CP6_NAME -# define XCHAL_CP6_NAME 0 -# define XCHAL_CP6_SA_CONTENTS_LIBDB_NUM 0 -# define XCHAL_CP6_SA_CONTENTS_LIBDB /* empty */ -#endif -#ifndef XCHAL_CP7_NAME -# define XCHAL_CP7_NAME 0 -# define XCHAL_CP7_SA_CONTENTS_LIBDB_NUM 0 -# define XCHAL_CP7_SA_CONTENTS_LIBDB /* empty */ -#endif - -#if XCHAL_CP_MASK == 0 -/* Filler info for unassigned coprocessors, to simplify arrays etc: */ -#define XCHAL_CP0_SA_SIZE 0 -#define XCHAL_CP0_SA_ALIGN 1 -#define XCHAL_CP1_SA_SIZE 0 -#define XCHAL_CP1_SA_ALIGN 1 -#define XCHAL_CP2_SA_SIZE 0 -#define XCHAL_CP2_SA_ALIGN 1 -#define XCHAL_CP3_SA_SIZE 0 -#define XCHAL_CP3_SA_ALIGN 1 -#define XCHAL_CP4_SA_SIZE 0 -#define XCHAL_CP4_SA_ALIGN 1 -#define XCHAL_CP5_SA_SIZE 0 -#define XCHAL_CP5_SA_ALIGN 1 -#define XCHAL_CP6_SA_SIZE 0 -#define XCHAL_CP6_SA_ALIGN 1 -#define XCHAL_CP7_SA_SIZE 0 -#define XCHAL_CP7_SA_ALIGN 1 -#endif - - -/* Indexing macros: */ -#define _XCHAL_CP_SA_SIZE(n) XCHAL_CP ## n ## _SA_SIZE -#define XCHAL_CP_SA_SIZE(n) _XCHAL_CP_SA_SIZE(n) /* n = 0 .. 7 */ -#define _XCHAL_CP_SA_ALIGN(n) XCHAL_CP ## n ## _SA_ALIGN -#define XCHAL_CP_SA_ALIGN(n) _XCHAL_CP_SA_ALIGN(n) /* n = 0 .. 7 */ - -#define XCHAL_CPEXTRA_SA_SIZE_TOR2 XCHAL_CPEXTRA_SA_SIZE /* Tor2Beta only - do not use */ - -/* Link-time HAL global variables that report coprocessor numbers by name - (names are case-preserved from the original TIE): */ -#if !defined(_ASMLANGUAGE) && !defined(_NOCLANGUAGE) && !defined(__ASSEMBLER__) -# define _XCJOIN(a,b) a ## b -# define XCJOIN(a,b) _XCJOIN(a,b) -# ifdef XCHAL_CP0_NAME -extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP0_IDENT); -extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP0_IDENT); -# endif -# ifdef XCHAL_CP1_NAME -extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP1_IDENT); -extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP1_IDENT); -# endif -# ifdef XCHAL_CP2_NAME -extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP2_IDENT); -extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP2_IDENT); -# endif -# ifdef XCHAL_CP3_NAME -extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP3_IDENT); -extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP3_IDENT); -# endif -# ifdef XCHAL_CP4_NAME -extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP4_IDENT); -extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP4_IDENT); -# endif -# ifdef XCHAL_CP5_NAME -extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP5_IDENT); -extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP5_IDENT); -# endif -# ifdef XCHAL_CP6_NAME -extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP6_IDENT); -extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP6_IDENT); -# endif -# ifdef XCHAL_CP7_NAME -extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP7_IDENT); -extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP7_IDENT); -# endif -#endif - - - - -/*---------------------------------------------------------------------- - DERIVED - ----------------------------------------------------------------------*/ - -#if XCHAL_HAVE_BE -#define XCHAL_INST_ILLN 0xD60F /* 2-byte illegal instruction, msb-first */ -#define XCHAL_INST_ILLN_BYTE0 0xD6 /* 2-byte illegal instruction, 1st byte */ -#define XCHAL_INST_ILLN_BYTE1 0x0F /* 2-byte illegal instruction, 2nd byte */ -#else -#define XCHAL_INST_ILLN 0xF06D /* 2-byte illegal instruction, lsb-first */ -#define XCHAL_INST_ILLN_BYTE0 0x6D /* 2-byte illegal instruction, 1st byte */ -#define XCHAL_INST_ILLN_BYTE1 0xF0 /* 2-byte illegal instruction, 2nd byte */ -#endif -/* Belongs in xtensa/hal.h: */ -#define XTHAL_INST_ILL 0x000000 /* 3-byte illegal instruction */ - - -/* - * Because information as to exactly which hardware version is targeted - * by a given software build is not always available, compile-time HAL - * Hardware-Release "_AT" macros are fuzzy (return 0, 1, or XCHAL_MAYBE): - * (Here "RELEASE" is now a misnomer; these are product *versions*, not the releases - * under which they are released. In the T10##.# era there was no distinction.) - */ -#if XCHAL_HW_CONFIGID_RELIABLE -# define XCHAL_HW_RELEASE_AT_OR_BELOW(major,minor) (XTHAL_REL_LE( XCHAL_HW_VERSION_MAJOR,XCHAL_HW_VERSION_MINOR, major,minor ) ? 1 : 0) -# define XCHAL_HW_RELEASE_AT_OR_ABOVE(major,minor) (XTHAL_REL_GE( XCHAL_HW_VERSION_MAJOR,XCHAL_HW_VERSION_MINOR, major,minor ) ? 1 : 0) -# define XCHAL_HW_RELEASE_AT(major,minor) (XTHAL_REL_EQ( XCHAL_HW_VERSION_MAJOR,XCHAL_HW_VERSION_MINOR, major,minor ) ? 1 : 0) -# define XCHAL_HW_RELEASE_MAJOR_AT(major) ((XCHAL_HW_VERSION_MAJOR == (major)) ? 1 : 0) -#else -# define XCHAL_HW_RELEASE_AT_OR_BELOW(major,minor) ( ((major) < 1040 && XCHAL_HAVE_XEA2) ? 0 \ - : ((major) > 1050 && XCHAL_HAVE_XEA1) ? 1 \ - : XTHAL_MAYBE ) -# define XCHAL_HW_RELEASE_AT_OR_ABOVE(major,minor) ( ((major) >= 2000 && XCHAL_HAVE_XEA1) ? 0 \ - : (XTHAL_REL_LE(major,minor, 1040,0) && XCHAL_HAVE_XEA2) ? 1 \ - : XTHAL_MAYBE ) -# define XCHAL_HW_RELEASE_AT(major,minor) ( (((major) < 1040 && XCHAL_HAVE_XEA2) || \ - ((major) >= 2000 && XCHAL_HAVE_XEA1)) ? 0 : XTHAL_MAYBE) -# define XCHAL_HW_RELEASE_MAJOR_AT(major) XCHAL_HW_RELEASE_AT(major,0) -#endif - -/* - * Specific errata: - */ - -/* - * Erratum T1020.H13, T1030.H7, T1040.H10, T1050.H4 (fixed in T1040.3 and T1050.1; - * relevant only in XEA1, kernel-vector mode, level-one interrupts and overflows enabled): - */ -#define XCHAL_MAYHAVE_ERRATUM_XEA1KWIN (XCHAL_HAVE_XEA1 && \ - (XCHAL_HW_RELEASE_AT_OR_BELOW(1040,2) != 0 \ - || XCHAL_HW_RELEASE_AT(1050,0))) - - - -#endif /*XTENSA_CONFIG_CORE_H*/ - +/* + * xtensa/config/core.h -- HAL definitions dependent on CORE configuration + * + * This header file is sometimes referred to as the "compile-time HAL" or CHAL. + * It pulls definitions tailored for a specific Xtensa processor configuration. + * + * Sources for binaries meant to be configuration-independent generally avoid + * including this file (they may use the configuration-specific HAL library). + * It is normal for the HAL library source itself to include this file. + */ + +/* + * Copyright (c) 2005-2010 Tensilica Inc. + * + * 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 XTENSA_CONFIG_CORE_H +#define XTENSA_CONFIG_CORE_H + +/* CONFIGURATION INDEPENDENT DEFINITIONS: */ +#ifdef __XTENSA__ +#include +#else +#include "../hal.h" +#endif + +/* CONFIGURATION SPECIFIC DEFINITIONS: */ +#ifdef __XTENSA__ +#include +#include +#include +#else +#include "core-isa.h" +#include "core-matmap.h" +#include "tie.h" +#endif + +#if defined (_ASMLANGUAGE) || defined (__ASSEMBLER__) +#ifdef __XTENSA__ +#include +#else +#include "tie-asm.h" +#endif +#endif /*_ASMLANGUAGE or __ASSEMBLER__*/ + + +/*---------------------------------------------------------------------- + GENERAL + ----------------------------------------------------------------------*/ + +/* + * Separators for macros that expand into arrays. + * These can be predefined by files that #include this one, + * when different separators are required. + */ +/* Element separator for macros that expand into 1-dimensional arrays: */ +#ifndef XCHAL_SEP +#define XCHAL_SEP , +#endif +/* Array separator for macros that expand into 2-dimensional arrays: */ +#ifndef XCHAL_SEP2 +#define XCHAL_SEP2 },{ +#endif + + + +/*---------------------------------------------------------------------- + ISA + ----------------------------------------------------------------------*/ + +#if XCHAL_HAVE_BE +# define XCHAL_HAVE_LE 0 +# define XCHAL_MEMORY_ORDER XTHAL_BIGENDIAN +#else +# define XCHAL_HAVE_LE 1 +# define XCHAL_MEMORY_ORDER XTHAL_LITTLEENDIAN +#endif + + + +/*---------------------------------------------------------------------- + INTERRUPTS + ----------------------------------------------------------------------*/ + +/* Indexing macros: */ +#define _XCHAL_INTLEVEL_MASK(n) XCHAL_INTLEVEL ## n ## _MASK +#define XCHAL_INTLEVEL_MASK(n) _XCHAL_INTLEVEL_MASK(n) /* n = 0 .. 15 */ +#define _XCHAL_INTLEVEL_ANDBELOWMASK(n) XCHAL_INTLEVEL ## n ## _ANDBELOW_MASK +#define XCHAL_INTLEVEL_ANDBELOW_MASK(n) _XCHAL_INTLEVEL_ANDBELOWMASK(n) /* n = 0 .. 15 */ +#define _XCHAL_INTLEVEL_NUM(n) XCHAL_INTLEVEL ## n ## _NUM +#define XCHAL_INTLEVEL_NUM(n) _XCHAL_INTLEVEL_NUM(n) /* n = 0 .. 15 */ +#define _XCHAL_INT_LEVEL(n) XCHAL_INT ## n ## _LEVEL +#define XCHAL_INT_LEVEL(n) _XCHAL_INT_LEVEL(n) /* n = 0 .. 31 */ +#define _XCHAL_INT_TYPE(n) XCHAL_INT ## n ## _TYPE +#define XCHAL_INT_TYPE(n) _XCHAL_INT_TYPE(n) /* n = 0 .. 31 */ +#define _XCHAL_TIMER_INTERRUPT(n) XCHAL_TIMER ## n ## _INTERRUPT +#define XCHAL_TIMER_INTERRUPT(n) _XCHAL_TIMER_INTERRUPT(n) /* n = 0 .. 3 */ + + +#define XCHAL_HAVE_HIGHLEVEL_INTERRUPTS XCHAL_HAVE_HIGHPRI_INTERRUPTS +#define XCHAL_NUM_LOWPRI_LEVELS 1 /* number of low-priority interrupt levels (always 1) */ +#define XCHAL_FIRST_HIGHPRI_LEVEL (XCHAL_NUM_LOWPRI_LEVELS+1) /* level of first high-priority interrupt (always 2) */ +/* Note: 1 <= LOWPRI_LEVELS <= EXCM_LEVEL < DEBUGLEVEL <= NUM_INTLEVELS < NMILEVEL <= 15 */ + +/* These values are constant for existing Xtensa processor implementations: */ +#define XCHAL_INTLEVEL0_MASK 0x00000000 +#define XCHAL_INTLEVEL8_MASK 0x00000000 +#define XCHAL_INTLEVEL9_MASK 0x00000000 +#define XCHAL_INTLEVEL10_MASK 0x00000000 +#define XCHAL_INTLEVEL11_MASK 0x00000000 +#define XCHAL_INTLEVEL12_MASK 0x00000000 +#define XCHAL_INTLEVEL13_MASK 0x00000000 +#define XCHAL_INTLEVEL14_MASK 0x00000000 +#define XCHAL_INTLEVEL15_MASK 0x00000000 + +/* Array of masks of interrupts at each interrupt level: */ +#define XCHAL_INTLEVEL_MASKS XCHAL_INTLEVEL0_MASK \ + XCHAL_SEP XCHAL_INTLEVEL1_MASK \ + XCHAL_SEP XCHAL_INTLEVEL2_MASK \ + XCHAL_SEP XCHAL_INTLEVEL3_MASK \ + XCHAL_SEP XCHAL_INTLEVEL4_MASK \ + XCHAL_SEP XCHAL_INTLEVEL5_MASK \ + XCHAL_SEP XCHAL_INTLEVEL6_MASK \ + XCHAL_SEP XCHAL_INTLEVEL7_MASK \ + XCHAL_SEP XCHAL_INTLEVEL8_MASK \ + XCHAL_SEP XCHAL_INTLEVEL9_MASK \ + XCHAL_SEP XCHAL_INTLEVEL10_MASK \ + XCHAL_SEP XCHAL_INTLEVEL11_MASK \ + XCHAL_SEP XCHAL_INTLEVEL12_MASK \ + XCHAL_SEP XCHAL_INTLEVEL13_MASK \ + XCHAL_SEP XCHAL_INTLEVEL14_MASK \ + XCHAL_SEP XCHAL_INTLEVEL15_MASK + +/* These values are constant for existing Xtensa processor implementations: */ +#define XCHAL_INTLEVEL0_ANDBELOW_MASK 0x00000000 +#define XCHAL_INTLEVEL8_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK +#define XCHAL_INTLEVEL9_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK +#define XCHAL_INTLEVEL10_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK +#define XCHAL_INTLEVEL11_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK +#define XCHAL_INTLEVEL12_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK +#define XCHAL_INTLEVEL13_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK +#define XCHAL_INTLEVEL14_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK +#define XCHAL_INTLEVEL15_ANDBELOW_MASK XCHAL_INTLEVEL7_ANDBELOW_MASK + +/* Mask of all low-priority interrupts: */ +#define XCHAL_LOWPRI_MASK XCHAL_INTLEVEL1_ANDBELOW_MASK + +/* Mask of all interrupts masked by PS.EXCM (or CEXCM): */ +#define XCHAL_EXCM_MASK XCHAL_INTLEVEL_ANDBELOW_MASK(XCHAL_EXCM_LEVEL) + +/* Array of masks of interrupts at each range 1..n of interrupt levels: */ +#define XCHAL_INTLEVEL_ANDBELOW_MASKS XCHAL_INTLEVEL0_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL1_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL2_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL3_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL4_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL5_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL6_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL7_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL8_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL9_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL10_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL11_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL12_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL13_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL14_ANDBELOW_MASK \ + XCHAL_SEP XCHAL_INTLEVEL15_ANDBELOW_MASK + +#if 0 /*XCHAL_HAVE_NMI*/ +/* NMI "interrupt level" (for use with EXCSAVE_n, EPS_n, EPC_n, RFI n): */ +# define XCHAL_NMILEVEL (XCHAL_NUM_INTLEVELS+1) +#endif + +/* Array of levels of each possible interrupt: */ +#define XCHAL_INT_LEVELS XCHAL_INT0_LEVEL \ + XCHAL_SEP XCHAL_INT1_LEVEL \ + XCHAL_SEP XCHAL_INT2_LEVEL \ + XCHAL_SEP XCHAL_INT3_LEVEL \ + XCHAL_SEP XCHAL_INT4_LEVEL \ + XCHAL_SEP XCHAL_INT5_LEVEL \ + XCHAL_SEP XCHAL_INT6_LEVEL \ + XCHAL_SEP XCHAL_INT7_LEVEL \ + XCHAL_SEP XCHAL_INT8_LEVEL \ + XCHAL_SEP XCHAL_INT9_LEVEL \ + XCHAL_SEP XCHAL_INT10_LEVEL \ + XCHAL_SEP XCHAL_INT11_LEVEL \ + XCHAL_SEP XCHAL_INT12_LEVEL \ + XCHAL_SEP XCHAL_INT13_LEVEL \ + XCHAL_SEP XCHAL_INT14_LEVEL \ + XCHAL_SEP XCHAL_INT15_LEVEL \ + XCHAL_SEP XCHAL_INT16_LEVEL \ + XCHAL_SEP XCHAL_INT17_LEVEL \ + XCHAL_SEP XCHAL_INT18_LEVEL \ + XCHAL_SEP XCHAL_INT19_LEVEL \ + XCHAL_SEP XCHAL_INT20_LEVEL \ + XCHAL_SEP XCHAL_INT21_LEVEL \ + XCHAL_SEP XCHAL_INT22_LEVEL \ + XCHAL_SEP XCHAL_INT23_LEVEL \ + XCHAL_SEP XCHAL_INT24_LEVEL \ + XCHAL_SEP XCHAL_INT25_LEVEL \ + XCHAL_SEP XCHAL_INT26_LEVEL \ + XCHAL_SEP XCHAL_INT27_LEVEL \ + XCHAL_SEP XCHAL_INT28_LEVEL \ + XCHAL_SEP XCHAL_INT29_LEVEL \ + XCHAL_SEP XCHAL_INT30_LEVEL \ + XCHAL_SEP XCHAL_INT31_LEVEL + +/* Array of types of each possible interrupt: */ +#define XCHAL_INT_TYPES XCHAL_INT0_TYPE \ + XCHAL_SEP XCHAL_INT1_TYPE \ + XCHAL_SEP XCHAL_INT2_TYPE \ + XCHAL_SEP XCHAL_INT3_TYPE \ + XCHAL_SEP XCHAL_INT4_TYPE \ + XCHAL_SEP XCHAL_INT5_TYPE \ + XCHAL_SEP XCHAL_INT6_TYPE \ + XCHAL_SEP XCHAL_INT7_TYPE \ + XCHAL_SEP XCHAL_INT8_TYPE \ + XCHAL_SEP XCHAL_INT9_TYPE \ + XCHAL_SEP XCHAL_INT10_TYPE \ + XCHAL_SEP XCHAL_INT11_TYPE \ + XCHAL_SEP XCHAL_INT12_TYPE \ + XCHAL_SEP XCHAL_INT13_TYPE \ + XCHAL_SEP XCHAL_INT14_TYPE \ + XCHAL_SEP XCHAL_INT15_TYPE \ + XCHAL_SEP XCHAL_INT16_TYPE \ + XCHAL_SEP XCHAL_INT17_TYPE \ + XCHAL_SEP XCHAL_INT18_TYPE \ + XCHAL_SEP XCHAL_INT19_TYPE \ + XCHAL_SEP XCHAL_INT20_TYPE \ + XCHAL_SEP XCHAL_INT21_TYPE \ + XCHAL_SEP XCHAL_INT22_TYPE \ + XCHAL_SEP XCHAL_INT23_TYPE \ + XCHAL_SEP XCHAL_INT24_TYPE \ + XCHAL_SEP XCHAL_INT25_TYPE \ + XCHAL_SEP XCHAL_INT26_TYPE \ + XCHAL_SEP XCHAL_INT27_TYPE \ + XCHAL_SEP XCHAL_INT28_TYPE \ + XCHAL_SEP XCHAL_INT29_TYPE \ + XCHAL_SEP XCHAL_INT30_TYPE \ + XCHAL_SEP XCHAL_INT31_TYPE + +/* Array of masks of interrupts for each type of interrupt: */ +#define XCHAL_INTTYPE_MASKS XCHAL_INTTYPE_MASK_UNCONFIGURED \ + XCHAL_SEP XCHAL_INTTYPE_MASK_SOFTWARE \ + XCHAL_SEP XCHAL_INTTYPE_MASK_EXTERN_EDGE \ + XCHAL_SEP XCHAL_INTTYPE_MASK_EXTERN_LEVEL \ + XCHAL_SEP XCHAL_INTTYPE_MASK_TIMER \ + XCHAL_SEP XCHAL_INTTYPE_MASK_NMI \ + XCHAL_SEP XCHAL_INTTYPE_MASK_WRITE_ERROR + +/* Interrupts that can be cleared using the INTCLEAR special register: */ +#define XCHAL_INTCLEARABLE_MASK (XCHAL_INTTYPE_MASK_SOFTWARE+XCHAL_INTTYPE_MASK_EXTERN_EDGE+XCHAL_INTTYPE_MASK_WRITE_ERROR) +/* Interrupts that can be triggered using the INTSET special register: */ +#define XCHAL_INTSETTABLE_MASK XCHAL_INTTYPE_MASK_SOFTWARE + +/* Array of interrupts assigned to each timer (CCOMPARE0 to CCOMPARE3): */ +#define XCHAL_TIMER_INTERRUPTS XCHAL_TIMER0_INTERRUPT \ + XCHAL_SEP XCHAL_TIMER1_INTERRUPT \ + XCHAL_SEP XCHAL_TIMER2_INTERRUPT \ + XCHAL_SEP XCHAL_TIMER3_INTERRUPT + + + +/* For backward compatibility and for the array macros, define macros for + * each unconfigured interrupt number (unfortunately, the value of + * XTHAL_INTTYPE_UNCONFIGURED is not zero): */ +#if XCHAL_NUM_INTERRUPTS == 0 +# define XCHAL_INT0_LEVEL 0 +# define XCHAL_INT0_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 1 +# define XCHAL_INT1_LEVEL 0 +# define XCHAL_INT1_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 2 +# define XCHAL_INT2_LEVEL 0 +# define XCHAL_INT2_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 3 +# define XCHAL_INT3_LEVEL 0 +# define XCHAL_INT3_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 4 +# define XCHAL_INT4_LEVEL 0 +# define XCHAL_INT4_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 5 +# define XCHAL_INT5_LEVEL 0 +# define XCHAL_INT5_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 6 +# define XCHAL_INT6_LEVEL 0 +# define XCHAL_INT6_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 7 +# define XCHAL_INT7_LEVEL 0 +# define XCHAL_INT7_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 8 +# define XCHAL_INT8_LEVEL 0 +# define XCHAL_INT8_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 9 +# define XCHAL_INT9_LEVEL 0 +# define XCHAL_INT9_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 10 +# define XCHAL_INT10_LEVEL 0 +# define XCHAL_INT10_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 11 +# define XCHAL_INT11_LEVEL 0 +# define XCHAL_INT11_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 12 +# define XCHAL_INT12_LEVEL 0 +# define XCHAL_INT12_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 13 +# define XCHAL_INT13_LEVEL 0 +# define XCHAL_INT13_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 14 +# define XCHAL_INT14_LEVEL 0 +# define XCHAL_INT14_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 15 +# define XCHAL_INT15_LEVEL 0 +# define XCHAL_INT15_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 16 +# define XCHAL_INT16_LEVEL 0 +# define XCHAL_INT16_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 17 +# define XCHAL_INT17_LEVEL 0 +# define XCHAL_INT17_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 18 +# define XCHAL_INT18_LEVEL 0 +# define XCHAL_INT18_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 19 +# define XCHAL_INT19_LEVEL 0 +# define XCHAL_INT19_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 20 +# define XCHAL_INT20_LEVEL 0 +# define XCHAL_INT20_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 21 +# define XCHAL_INT21_LEVEL 0 +# define XCHAL_INT21_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 22 +# define XCHAL_INT22_LEVEL 0 +# define XCHAL_INT22_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 23 +# define XCHAL_INT23_LEVEL 0 +# define XCHAL_INT23_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 24 +# define XCHAL_INT24_LEVEL 0 +# define XCHAL_INT24_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 25 +# define XCHAL_INT25_LEVEL 0 +# define XCHAL_INT25_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 26 +# define XCHAL_INT26_LEVEL 0 +# define XCHAL_INT26_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 27 +# define XCHAL_INT27_LEVEL 0 +# define XCHAL_INT27_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 28 +# define XCHAL_INT28_LEVEL 0 +# define XCHAL_INT28_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 29 +# define XCHAL_INT29_LEVEL 0 +# define XCHAL_INT29_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 30 +# define XCHAL_INT30_LEVEL 0 +# define XCHAL_INT30_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif +#if XCHAL_NUM_INTERRUPTS <= 31 +# define XCHAL_INT31_LEVEL 0 +# define XCHAL_INT31_TYPE XTHAL_INTTYPE_UNCONFIGURED +#endif + + +/* + * Masks and levels corresponding to each *external* interrupt. + */ + +#define XCHAL_EXTINT0_MASK (1 << XCHAL_EXTINT0_NUM) +#define XCHAL_EXTINT0_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT0_NUM) +#define XCHAL_EXTINT1_MASK (1 << XCHAL_EXTINT1_NUM) +#define XCHAL_EXTINT1_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT1_NUM) +#define XCHAL_EXTINT2_MASK (1 << XCHAL_EXTINT2_NUM) +#define XCHAL_EXTINT2_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT2_NUM) +#define XCHAL_EXTINT3_MASK (1 << XCHAL_EXTINT3_NUM) +#define XCHAL_EXTINT3_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT3_NUM) +#define XCHAL_EXTINT4_MASK (1 << XCHAL_EXTINT4_NUM) +#define XCHAL_EXTINT4_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT4_NUM) +#define XCHAL_EXTINT5_MASK (1 << XCHAL_EXTINT5_NUM) +#define XCHAL_EXTINT5_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT5_NUM) +#define XCHAL_EXTINT6_MASK (1 << XCHAL_EXTINT6_NUM) +#define XCHAL_EXTINT6_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT6_NUM) +#define XCHAL_EXTINT7_MASK (1 << XCHAL_EXTINT7_NUM) +#define XCHAL_EXTINT7_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT7_NUM) +#define XCHAL_EXTINT8_MASK (1 << XCHAL_EXTINT8_NUM) +#define XCHAL_EXTINT8_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT8_NUM) +#define XCHAL_EXTINT9_MASK (1 << XCHAL_EXTINT9_NUM) +#define XCHAL_EXTINT9_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT9_NUM) +#define XCHAL_EXTINT10_MASK (1 << XCHAL_EXTINT10_NUM) +#define XCHAL_EXTINT10_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT10_NUM) +#define XCHAL_EXTINT11_MASK (1 << XCHAL_EXTINT11_NUM) +#define XCHAL_EXTINT11_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT11_NUM) +#define XCHAL_EXTINT12_MASK (1 << XCHAL_EXTINT12_NUM) +#define XCHAL_EXTINT12_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT12_NUM) +#define XCHAL_EXTINT13_MASK (1 << XCHAL_EXTINT13_NUM) +#define XCHAL_EXTINT13_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT13_NUM) +#define XCHAL_EXTINT14_MASK (1 << XCHAL_EXTINT14_NUM) +#define XCHAL_EXTINT14_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT14_NUM) +#define XCHAL_EXTINT15_MASK (1 << XCHAL_EXTINT15_NUM) +#define XCHAL_EXTINT15_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT15_NUM) +#define XCHAL_EXTINT16_MASK (1 << XCHAL_EXTINT16_NUM) +#define XCHAL_EXTINT16_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT16_NUM) +#define XCHAL_EXTINT17_MASK (1 << XCHAL_EXTINT17_NUM) +#define XCHAL_EXTINT17_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT17_NUM) +#define XCHAL_EXTINT18_MASK (1 << XCHAL_EXTINT18_NUM) +#define XCHAL_EXTINT18_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT18_NUM) +#define XCHAL_EXTINT19_MASK (1 << XCHAL_EXTINT19_NUM) +#define XCHAL_EXTINT19_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT19_NUM) +#define XCHAL_EXTINT20_MASK (1 << XCHAL_EXTINT20_NUM) +#define XCHAL_EXTINT20_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT20_NUM) +#define XCHAL_EXTINT21_MASK (1 << XCHAL_EXTINT21_NUM) +#define XCHAL_EXTINT21_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT21_NUM) +#define XCHAL_EXTINT22_MASK (1 << XCHAL_EXTINT22_NUM) +#define XCHAL_EXTINT22_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT22_NUM) +#define XCHAL_EXTINT23_MASK (1 << XCHAL_EXTINT23_NUM) +#define XCHAL_EXTINT23_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT23_NUM) +#define XCHAL_EXTINT24_MASK (1 << XCHAL_EXTINT24_NUM) +#define XCHAL_EXTINT24_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT24_NUM) +#define XCHAL_EXTINT25_MASK (1 << XCHAL_EXTINT25_NUM) +#define XCHAL_EXTINT25_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT25_NUM) +#define XCHAL_EXTINT26_MASK (1 << XCHAL_EXTINT26_NUM) +#define XCHAL_EXTINT26_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT26_NUM) +#define XCHAL_EXTINT27_MASK (1 << XCHAL_EXTINT27_NUM) +#define XCHAL_EXTINT27_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT27_NUM) +#define XCHAL_EXTINT28_MASK (1 << XCHAL_EXTINT28_NUM) +#define XCHAL_EXTINT28_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT28_NUM) +#define XCHAL_EXTINT29_MASK (1 << XCHAL_EXTINT29_NUM) +#define XCHAL_EXTINT29_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT29_NUM) +#define XCHAL_EXTINT30_MASK (1 << XCHAL_EXTINT30_NUM) +#define XCHAL_EXTINT30_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT30_NUM) +#define XCHAL_EXTINT31_MASK (1 << XCHAL_EXTINT31_NUM) +#define XCHAL_EXTINT31_LEVEL XCHAL_INT_LEVEL(XCHAL_EXTINT31_NUM) + + +/*---------------------------------------------------------------------- + EXCEPTIONS and VECTORS + ----------------------------------------------------------------------*/ + +/* For backward compatibility ONLY -- DO NOT USE (will be removed in future release): */ +#define XCHAL_HAVE_OLD_EXC_ARCH XCHAL_HAVE_XEA1 /* (DEPRECATED) 1 if old exception architecture (XEA1), 0 otherwise (eg. XEA2) */ +#define XCHAL_HAVE_EXCM XCHAL_HAVE_XEA2 /* (DEPRECATED) 1 if PS.EXCM bit exists (currently equals XCHAL_HAVE_TLBS) */ +#ifdef XCHAL_USER_VECTOR_VADDR +#define XCHAL_PROGRAMEXC_VECTOR_VADDR XCHAL_USER_VECTOR_VADDR +#define XCHAL_USEREXC_VECTOR_VADDR XCHAL_USER_VECTOR_VADDR +#endif +#ifdef XCHAL_USER_VECTOR_PADDR +# define XCHAL_PROGRAMEXC_VECTOR_PADDR XCHAL_USER_VECTOR_PADDR +# define XCHAL_USEREXC_VECTOR_PADDR XCHAL_USER_VECTOR_PADDR +#endif +#ifdef XCHAL_KERNEL_VECTOR_VADDR +# define XCHAL_STACKEDEXC_VECTOR_VADDR XCHAL_KERNEL_VECTOR_VADDR +# define XCHAL_KERNELEXC_VECTOR_VADDR XCHAL_KERNEL_VECTOR_VADDR +#endif +#ifdef XCHAL_KERNEL_VECTOR_PADDR +# define XCHAL_STACKEDEXC_VECTOR_PADDR XCHAL_KERNEL_VECTOR_PADDR +# define XCHAL_KERNELEXC_VECTOR_PADDR XCHAL_KERNEL_VECTOR_PADDR +#endif + +#if 0 +#if XCHAL_HAVE_DEBUG +# define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL_VECTOR_VADDR(XCHAL_DEBUGLEVEL) +/* This one should only get defined if the corresponding intlevel paddr macro exists: */ +# define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL_VECTOR_PADDR(XCHAL_DEBUGLEVEL) +#endif +#endif + +/* Indexing macros: */ +#define _XCHAL_INTLEVEL_VECTOR_VADDR(n) XCHAL_INTLEVEL ## n ## _VECTOR_VADDR +#define XCHAL_INTLEVEL_VECTOR_VADDR(n) _XCHAL_INTLEVEL_VECTOR_VADDR(n) /* n = 0 .. 15 */ + +/* + * General Exception Causes + * (values of EXCCAUSE special register set by general exceptions, + * which vector to the user, kernel, or double-exception vectors). + * + * DEPRECATED. Please use the equivalent EXCCAUSE_xxx macros + * defined in . (Note that these have slightly + * different names, they don't just have the XCHAL_ prefix removed.) + */ +#define XCHAL_EXCCAUSE_ILLEGAL_INSTRUCTION 0 /* Illegal Instruction */ +#define XCHAL_EXCCAUSE_SYSTEM_CALL 1 /* System Call */ +#define XCHAL_EXCCAUSE_INSTRUCTION_FETCH_ERROR 2 /* Instruction Fetch Error */ +#define XCHAL_EXCCAUSE_LOAD_STORE_ERROR 3 /* Load Store Error */ +#define XCHAL_EXCCAUSE_LEVEL1_INTERRUPT 4 /* Level 1 Interrupt */ +#define XCHAL_EXCCAUSE_ALLOCA 5 /* Stack Extension Assist */ +#define XCHAL_EXCCAUSE_INTEGER_DIVIDE_BY_ZERO 6 /* Integer Divide by Zero */ +#define XCHAL_EXCCAUSE_SPECULATION 7 /* Speculation */ +#define XCHAL_EXCCAUSE_PRIVILEGED 8 /* Privileged Instruction */ +#define XCHAL_EXCCAUSE_UNALIGNED 9 /* Unaligned Load Store */ +/*10..15 reserved*/ +#define XCHAL_EXCCAUSE_ITLB_MISS 16 /* ITlb Miss Exception */ +#define XCHAL_EXCCAUSE_ITLB_MULTIHIT 17 /* ITlb Mutltihit Exception */ +#define XCHAL_EXCCAUSE_ITLB_PRIVILEGE 18 /* ITlb Privilege Exception */ +#define XCHAL_EXCCAUSE_ITLB_SIZE_RESTRICTION 19 /* ITlb Size Restriction Exception */ +#define XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE 20 /* Fetch Cache Attribute Exception */ +/*21..23 reserved*/ +#define XCHAL_EXCCAUSE_DTLB_MISS 24 /* DTlb Miss Exception */ +#define XCHAL_EXCCAUSE_DTLB_MULTIHIT 25 /* DTlb Multihit Exception */ +#define XCHAL_EXCCAUSE_DTLB_PRIVILEGE 26 /* DTlb Privilege Exception */ +#define XCHAL_EXCCAUSE_DTLB_SIZE_RESTRICTION 27 /* DTlb Size Restriction Exception */ +#define XCHAL_EXCCAUSE_LOAD_CACHE_ATTRIBUTE 28 /* Load Cache Attribute Exception */ +#define XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE 29 /* Store Cache Attribute Exception */ +/*30..31 reserved*/ +#define XCHAL_EXCCAUSE_COPROCESSOR0_DISABLED 32 /* Coprocessor 0 disabled */ +#define XCHAL_EXCCAUSE_COPROCESSOR1_DISABLED 33 /* Coprocessor 1 disabled */ +#define XCHAL_EXCCAUSE_COPROCESSOR2_DISABLED 34 /* Coprocessor 2 disabled */ +#define XCHAL_EXCCAUSE_COPROCESSOR3_DISABLED 35 /* Coprocessor 3 disabled */ +#define XCHAL_EXCCAUSE_COPROCESSOR4_DISABLED 36 /* Coprocessor 4 disabled */ +#define XCHAL_EXCCAUSE_COPROCESSOR5_DISABLED 37 /* Coprocessor 5 disabled */ +#define XCHAL_EXCCAUSE_COPROCESSOR6_DISABLED 38 /* Coprocessor 6 disabled */ +#define XCHAL_EXCCAUSE_COPROCESSOR7_DISABLED 39 /* Coprocessor 7 disabled */ +#define XCHAL_EXCCAUSE_FLOATING_POINT 40 /* Floating Point Exception */ +/*40..63 reserved*/ + + +/* + * Miscellaneous special register fields. + * + * For each special register, and each field within each register: + * XCHAL__VALIDMASK is the set of bits defined in the register. + * XCHAL___BITS is the number of bits in the field. + * XCHAL___NUM is 2^bits, the number of possible values + * of the field. + * XCHAL___SHIFT is the position of the field within + * the register, starting from the least significant bit. + * + * DEPRECATED. Please use the equivalent macros defined in + * . (Note that these have different names.) + */ + +/* DBREAKC (special register number 160): */ +#define XCHAL_DBREAKC_VALIDMASK 0xC000003F +#define XCHAL_DBREAKC_MASK_BITS 6 +#define XCHAL_DBREAKC_MASK_NUM 64 +#define XCHAL_DBREAKC_MASK_SHIFT 0 +#define XCHAL_DBREAKC_MASK_MASK 0x0000003F +#define XCHAL_DBREAKC_LOADBREAK_BITS 1 +#define XCHAL_DBREAKC_LOADBREAK_NUM 2 +#define XCHAL_DBREAKC_LOADBREAK_SHIFT 30 +#define XCHAL_DBREAKC_LOADBREAK_MASK 0x40000000 +#define XCHAL_DBREAKC_STOREBREAK_BITS 1 +#define XCHAL_DBREAKC_STOREBREAK_NUM 2 +#define XCHAL_DBREAKC_STOREBREAK_SHIFT 31 +#define XCHAL_DBREAKC_STOREBREAK_MASK 0x80000000 +/* PS (special register number 230): */ +#define XCHAL_PS_VALIDMASK 0x00070F3F +#define XCHAL_PS_INTLEVEL_BITS 4 +#define XCHAL_PS_INTLEVEL_NUM 16 +#define XCHAL_PS_INTLEVEL_SHIFT 0 +#define XCHAL_PS_INTLEVEL_MASK 0x0000000F +#define XCHAL_PS_EXCM_BITS 1 +#define XCHAL_PS_EXCM_NUM 2 +#define XCHAL_PS_EXCM_SHIFT 4 +#define XCHAL_PS_EXCM_MASK 0x00000010 +#define XCHAL_PS_UM_BITS 1 +#define XCHAL_PS_UM_NUM 2 +#define XCHAL_PS_UM_SHIFT 5 +#define XCHAL_PS_UM_MASK 0x00000020 +#define XCHAL_PS_RING_BITS 2 +#define XCHAL_PS_RING_NUM 4 +#define XCHAL_PS_RING_SHIFT 6 +#define XCHAL_PS_RING_MASK 0x000000C0 +#define XCHAL_PS_OWB_BITS 4 +#define XCHAL_PS_OWB_NUM 16 +#define XCHAL_PS_OWB_SHIFT 8 +#define XCHAL_PS_OWB_MASK 0x00000F00 +#define XCHAL_PS_CALLINC_BITS 2 +#define XCHAL_PS_CALLINC_NUM 4 +#define XCHAL_PS_CALLINC_SHIFT 16 +#define XCHAL_PS_CALLINC_MASK 0x00030000 +#define XCHAL_PS_WOE_BITS 1 +#define XCHAL_PS_WOE_NUM 2 +#define XCHAL_PS_WOE_SHIFT 18 +#define XCHAL_PS_WOE_MASK 0x00040000 +/* EXCCAUSE (special register number 232): */ +#define XCHAL_EXCCAUSE_VALIDMASK 0x0000003F +#define XCHAL_EXCCAUSE_BITS 6 +#define XCHAL_EXCCAUSE_NUM 64 +#define XCHAL_EXCCAUSE_SHIFT 0 +#define XCHAL_EXCCAUSE_MASK 0x0000003F +/* DEBUGCAUSE (special register number 233): */ +#define XCHAL_DEBUGCAUSE_VALIDMASK 0x0000003F +#define XCHAL_DEBUGCAUSE_ICOUNT_BITS 1 +#define XCHAL_DEBUGCAUSE_ICOUNT_NUM 2 +#define XCHAL_DEBUGCAUSE_ICOUNT_SHIFT 0 +#define XCHAL_DEBUGCAUSE_ICOUNT_MASK 0x00000001 +#define XCHAL_DEBUGCAUSE_IBREAK_BITS 1 +#define XCHAL_DEBUGCAUSE_IBREAK_NUM 2 +#define XCHAL_DEBUGCAUSE_IBREAK_SHIFT 1 +#define XCHAL_DEBUGCAUSE_IBREAK_MASK 0x00000002 +#define XCHAL_DEBUGCAUSE_DBREAK_BITS 1 +#define XCHAL_DEBUGCAUSE_DBREAK_NUM 2 +#define XCHAL_DEBUGCAUSE_DBREAK_SHIFT 2 +#define XCHAL_DEBUGCAUSE_DBREAK_MASK 0x00000004 +#define XCHAL_DEBUGCAUSE_BREAK_BITS 1 +#define XCHAL_DEBUGCAUSE_BREAK_NUM 2 +#define XCHAL_DEBUGCAUSE_BREAK_SHIFT 3 +#define XCHAL_DEBUGCAUSE_BREAK_MASK 0x00000008 +#define XCHAL_DEBUGCAUSE_BREAKN_BITS 1 +#define XCHAL_DEBUGCAUSE_BREAKN_NUM 2 +#define XCHAL_DEBUGCAUSE_BREAKN_SHIFT 4 +#define XCHAL_DEBUGCAUSE_BREAKN_MASK 0x00000010 +#define XCHAL_DEBUGCAUSE_DEBUGINT_BITS 1 +#define XCHAL_DEBUGCAUSE_DEBUGINT_NUM 2 +#define XCHAL_DEBUGCAUSE_DEBUGINT_SHIFT 5 +#define XCHAL_DEBUGCAUSE_DEBUGINT_MASK 0x00000020 + + + + +/*---------------------------------------------------------------------- + TIMERS + ----------------------------------------------------------------------*/ + +/*#define XCHAL_HAVE_TIMERS XCHAL_HAVE_CCOUNT*/ + + + +/*---------------------------------------------------------------------- + INTERNAL I/D RAM/ROMs and XLMI + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_IROM XCHAL_NUM_INSTROM /* (DEPRECATED) */ +#define XCHAL_NUM_IRAM XCHAL_NUM_INSTRAM /* (DEPRECATED) */ +#define XCHAL_NUM_DROM XCHAL_NUM_DATAROM /* (DEPRECATED) */ +#define XCHAL_NUM_DRAM XCHAL_NUM_DATARAM /* (DEPRECATED) */ + +#define XCHAL_IROM0_VADDR XCHAL_INSTROM0_VADDR /* (DEPRECATED) */ +#define XCHAL_IROM0_PADDR XCHAL_INSTROM0_PADDR /* (DEPRECATED) */ +#define XCHAL_IROM0_SIZE XCHAL_INSTROM0_SIZE /* (DEPRECATED) */ +#define XCHAL_IROM1_VADDR XCHAL_INSTROM1_VADDR /* (DEPRECATED) */ +#define XCHAL_IROM1_PADDR XCHAL_INSTROM1_PADDR /* (DEPRECATED) */ +#define XCHAL_IROM1_SIZE XCHAL_INSTROM1_SIZE /* (DEPRECATED) */ +#define XCHAL_IRAM0_VADDR XCHAL_INSTRAM0_VADDR /* (DEPRECATED) */ +#define XCHAL_IRAM0_PADDR XCHAL_INSTRAM0_PADDR /* (DEPRECATED) */ +#define XCHAL_IRAM0_SIZE XCHAL_INSTRAM0_SIZE /* (DEPRECATED) */ +#define XCHAL_IRAM1_VADDR XCHAL_INSTRAM1_VADDR /* (DEPRECATED) */ +#define XCHAL_IRAM1_PADDR XCHAL_INSTRAM1_PADDR /* (DEPRECATED) */ +#define XCHAL_IRAM1_SIZE XCHAL_INSTRAM1_SIZE /* (DEPRECATED) */ +#define XCHAL_DROM0_VADDR XCHAL_DATAROM0_VADDR /* (DEPRECATED) */ +#define XCHAL_DROM0_PADDR XCHAL_DATAROM0_PADDR /* (DEPRECATED) */ +#define XCHAL_DROM0_SIZE XCHAL_DATAROM0_SIZE /* (DEPRECATED) */ +#define XCHAL_DROM1_VADDR XCHAL_DATAROM1_VADDR /* (DEPRECATED) */ +#define XCHAL_DROM1_PADDR XCHAL_DATAROM1_PADDR /* (DEPRECATED) */ +#define XCHAL_DROM1_SIZE XCHAL_DATAROM1_SIZE /* (DEPRECATED) */ +#define XCHAL_DRAM0_VADDR XCHAL_DATARAM0_VADDR /* (DEPRECATED) */ +#define XCHAL_DRAM0_PADDR XCHAL_DATARAM0_PADDR /* (DEPRECATED) */ +#define XCHAL_DRAM0_SIZE XCHAL_DATARAM0_SIZE /* (DEPRECATED) */ +#define XCHAL_DRAM1_VADDR XCHAL_DATARAM1_VADDR /* (DEPRECATED) */ +#define XCHAL_DRAM1_PADDR XCHAL_DATARAM1_PADDR /* (DEPRECATED) */ +#define XCHAL_DRAM1_SIZE XCHAL_DATARAM1_SIZE /* (DEPRECATED) */ + + + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + + +/* Default PREFCTL value to enable prefetch. */ +#define XCHAL_CACHE_PREFCTL_DEFAULT 0x44 + + +/* Max for both I-cache and D-cache (used for general alignment): */ +#if XCHAL_ICACHE_LINESIZE > XCHAL_DCACHE_LINESIZE +# define XCHAL_CACHE_LINEWIDTH_MAX XCHAL_ICACHE_LINEWIDTH +# define XCHAL_CACHE_LINESIZE_MAX XCHAL_ICACHE_LINESIZE +#else +# define XCHAL_CACHE_LINEWIDTH_MAX XCHAL_DCACHE_LINEWIDTH +# define XCHAL_CACHE_LINESIZE_MAX XCHAL_DCACHE_LINESIZE +#endif + +#define XCHAL_ICACHE_SETSIZE (1< XCHAL_DCACHE_SETWIDTH +# define XCHAL_CACHE_SETWIDTH_MAX XCHAL_ICACHE_SETWIDTH +# define XCHAL_CACHE_SETSIZE_MAX XCHAL_ICACHE_SETSIZE +#else +# define XCHAL_CACHE_SETWIDTH_MAX XCHAL_DCACHE_SETWIDTH +# define XCHAL_CACHE_SETSIZE_MAX XCHAL_DCACHE_SETSIZE +#endif + +/* Instruction cache tag bits: */ +#define XCHAL_ICACHE_TAG_V_SHIFT 0 +#define XCHAL_ICACHE_TAG_V 0x1 /* valid bit */ +#if XCHAL_ICACHE_WAYS > 1 +# define XCHAL_ICACHE_TAG_F_SHIFT 1 +# define XCHAL_ICACHE_TAG_F 0x2 /* fill (LRU) bit */ +#else +# define XCHAL_ICACHE_TAG_F_SHIFT 0 +# define XCHAL_ICACHE_TAG_F 0 /* no fill (LRU) bit */ +#endif +#if XCHAL_ICACHE_LINE_LOCKABLE +# define XCHAL_ICACHE_TAG_L_SHIFT (XCHAL_ICACHE_TAG_F_SHIFT+1) +# define XCHAL_ICACHE_TAG_L (1 << XCHAL_ICACHE_TAG_L_SHIFT) /* lock bit */ +#else +# define XCHAL_ICACHE_TAG_L_SHIFT XCHAL_ICACHE_TAG_F_SHIFT +# define XCHAL_ICACHE_TAG_L 0 /* no lock bit */ +#endif +/* Data cache tag bits: */ +#define XCHAL_DCACHE_TAG_V_SHIFT 0 +#define XCHAL_DCACHE_TAG_V 0x1 /* valid bit */ +#if XCHAL_DCACHE_WAYS > 1 +# define XCHAL_DCACHE_TAG_F_SHIFT 1 +# define XCHAL_DCACHE_TAG_F 0x2 /* fill (LRU) bit */ +#else +# define XCHAL_DCACHE_TAG_F_SHIFT 0 +# define XCHAL_DCACHE_TAG_F 0 /* no fill (LRU) bit */ +#endif +#if XCHAL_DCACHE_IS_WRITEBACK +# define XCHAL_DCACHE_TAG_D_SHIFT (XCHAL_DCACHE_TAG_F_SHIFT+1) +# define XCHAL_DCACHE_TAG_D (1 << XCHAL_DCACHE_TAG_D_SHIFT) /* dirty bit */ +#else +# define XCHAL_DCACHE_TAG_D_SHIFT XCHAL_DCACHE_TAG_F_SHIFT +# define XCHAL_DCACHE_TAG_D 0 /* no dirty bit */ +#endif +#if XCHAL_DCACHE_LINE_LOCKABLE +# define XCHAL_DCACHE_TAG_L_SHIFT (XCHAL_DCACHE_TAG_D_SHIFT+1) +# define XCHAL_DCACHE_TAG_L (1 << XCHAL_DCACHE_TAG_D_SHIFT) /* lock bit */ +#else +# define XCHAL_DCACHE_TAG_L_SHIFT XCHAL_DCACHE_TAG_D_SHIFT +# define XCHAL_DCACHE_TAG_L 0 /* no lock bit */ +#endif + + +/*---------------------------------------------------------------------- + MMU + ----------------------------------------------------------------------*/ + +/* See for more details. */ + +/* Has different semantic in open source headers (where it means HAVE_PTP_MMU), + so comment out starting with RB-2008.3 release; later, might get + get reintroduced as a synonym for XCHAL_HAVE_PTP_MMU instead: */ +/*#define XCHAL_HAVE_MMU XCHAL_HAVE_TLBS*/ /* (DEPRECATED; use XCHAL_HAVE_TLBS instead) */ + +/* Indexing macros: */ +#define _XCHAL_ITLB_SET(n,_what) XCHAL_ITLB_SET ## n ## _what +#define XCHAL_ITLB_SET(n,what) _XCHAL_ITLB_SET(n, _ ## what ) +#define _XCHAL_ITLB_SET_E(n,i,_what) XCHAL_ITLB_SET ## n ## _E ## i ## _what +#define XCHAL_ITLB_SET_E(n,i,what) _XCHAL_ITLB_SET_E(n,i, _ ## what ) +#define _XCHAL_DTLB_SET(n,_what) XCHAL_DTLB_SET ## n ## _what +#define XCHAL_DTLB_SET(n,what) _XCHAL_DTLB_SET(n, _ ## what ) +#define _XCHAL_DTLB_SET_E(n,i,_what) XCHAL_DTLB_SET ## n ## _E ## i ## _what +#define XCHAL_DTLB_SET_E(n,i,what) _XCHAL_DTLB_SET_E(n,i, _ ## what ) +/* + * Example use: XCHAL_ITLB_SET(XCHAL_ITLB_ARF_SET0,ENTRIES) + * to get the value of XCHAL_ITLB_SET_ENTRIES where is the first auto-refill set. + */ + +/* Number of entries per autorefill way: */ +#define XCHAL_ITLB_ARF_ENTRIES (1< 0 && XCHAL_DTLB_ARF_WAYS > 0 && XCHAL_MMU_RINGS >= 2 +# define XCHAL_HAVE_PTP_MMU 1 /* have full MMU (with page table [autorefill] and protection) */ +#else +# define XCHAL_HAVE_PTP_MMU 0 /* don't have full MMU */ +#endif +#endif + +/* + * For full MMUs, report kernel RAM segment and kernel I/O segment static page mappings: + */ +#if XCHAL_HAVE_PTP_MMU && !XCHAL_HAVE_SPANNING_WAY +#define XCHAL_KSEG_CACHED_VADDR 0xD0000000 /* virt.addr of kernel RAM cached static map */ +#define XCHAL_KSEG_CACHED_PADDR 0x00000000 /* phys.addr of kseg_cached */ +#define XCHAL_KSEG_CACHED_SIZE 0x08000000 /* size in bytes of kseg_cached (assumed power of 2!!!) */ +#define XCHAL_KSEG_BYPASS_VADDR 0xD8000000 /* virt.addr of kernel RAM bypass (uncached) static map */ +#define XCHAL_KSEG_BYPASS_PADDR 0x00000000 /* phys.addr of kseg_bypass */ +#define XCHAL_KSEG_BYPASS_SIZE 0x08000000 /* size in bytes of kseg_bypass (assumed power of 2!!!) */ + +#define XCHAL_KIO_CACHED_VADDR 0xE0000000 /* virt.addr of kernel I/O cached static map */ +#define XCHAL_KIO_CACHED_PADDR 0xF0000000 /* phys.addr of kio_cached */ +#define XCHAL_KIO_CACHED_SIZE 0x10000000 /* size in bytes of kio_cached (assumed power of 2!!!) */ +#define XCHAL_KIO_BYPASS_VADDR 0xF0000000 /* virt.addr of kernel I/O bypass (uncached) static map */ +#define XCHAL_KIO_BYPASS_PADDR 0xF0000000 /* phys.addr of kio_bypass */ +#define XCHAL_KIO_BYPASS_SIZE 0x10000000 /* size in bytes of kio_bypass (assumed power of 2!!!) */ + +#define XCHAL_SEG_MAPPABLE_VADDR 0x00000000 /* start of largest non-static-mapped virtual addr area */ +#define XCHAL_SEG_MAPPABLE_SIZE 0xD0000000 /* size in bytes of " */ +/* define XCHAL_SEG_MAPPABLE2_xxx if more areas present, sorted in order of descending size. */ +#endif + + +/*---------------------------------------------------------------------- + MISC + ----------------------------------------------------------------------*/ + +/* Data alignment required if used for instructions: */ +#if XCHAL_INST_FETCH_WIDTH > XCHAL_DATA_WIDTH +# define XCHAL_ALIGN_MAX XCHAL_INST_FETCH_WIDTH +#else +# define XCHAL_ALIGN_MAX XCHAL_DATA_WIDTH +#endif + +/* + * Names kept for backward compatibility. + * (Here "RELEASE" is now a misnomer; these are product *versions*, not the releases + * under which they are released. In the T10##.# era there was no distinction.) + */ +#define XCHAL_HW_RELEASE_MAJOR XCHAL_HW_VERSION_MAJOR +#define XCHAL_HW_RELEASE_MINOR XCHAL_HW_VERSION_MINOR +#define XCHAL_HW_RELEASE_NAME XCHAL_HW_VERSION_NAME + + + + +/*---------------------------------------------------------------------- + COPROCESSORS and EXTRA STATE + ----------------------------------------------------------------------*/ + +#define XCHAL_EXTRA_SA_SIZE XCHAL_NCP_SA_SIZE +#define XCHAL_EXTRA_SA_ALIGN XCHAL_NCP_SA_ALIGN +#define XCHAL_CPEXTRA_SA_SIZE XCHAL_TOTAL_SA_SIZE +#define XCHAL_CPEXTRA_SA_ALIGN XCHAL_TOTAL_SA_ALIGN + +#if defined (_ASMLANGUAGE) || defined (__ASSEMBLER__) + + /* Invoked at start of save area load/store sequence macro to setup macro + * internal offsets. Not usually invoked directly. + * continue 0 for 1st sequence, 1 for subsequent consecutive ones. + * totofs offset from original ptr to next load/store location. + */ + .macro xchal_sa_start continue totofs + .ifeq \continue + .set .Lxchal_pofs_, 0 /* offset from original ptr to current \ptr */ + .set .Lxchal_ofs_, 0 /* offset from current \ptr to next load/store location */ + .endif + .if \totofs + 1 /* if totofs specified (not -1) */ + .set .Lxchal_ofs_, \totofs - .Lxchal_pofs_ /* specific offset from original ptr */ + .endif + .endm + + /* Align portion of save area and bring ptr in range if necessary. + * Used by save area load/store sequences. Not usually invoked directly. + * Allows combining multiple (sub-)sequences arbitrarily. + * ptr pointer to save area (may be off, see .Lxchal_pofs_) + * minofs,maxofs range of offset from cur ptr to next load/store loc; + * minofs <= 0 <= maxofs (0 must always be valid offset) + * range must be within +/- 30kB or so. + * ofsalign alignment granularity of minofs .. maxofs (pow of 2) + * (restriction on offset from ptr to next load/store loc) + * totalign align from orig ptr to next load/store loc (pow of 2) + */ + .macro xchal_sa_align ptr minofs maxofs ofsalign totalign + .set .Lxchal_ofs_, ((.Lxchal_pofs_ + .Lxchal_ofs_ + \totalign - 1) & -\totalign) - .Lxchal_pofs_ + /* If necessary, adjust \ptr to bring .Lxchal_ofs_ in acceptable range: */ + .if (((\maxofs) - .Lxchal_ofs_) & 0xC0000000) | ((.Lxchal_ofs_ - (\minofs)) & 0xC0000000) | (.Lxchal_ofs_ & (\ofsalign-1)) + .set .Ligmask, 0xFFFFFFFF /* TODO: optimize to addmi, per aligns and .Lxchal_ofs_ */ + addi \ptr, \ptr, (.Lxchal_ofs_ & .Ligmask) + .set .Lxchal_pofs_, .Lxchal_pofs_ + (.Lxchal_ofs_ & .Ligmask) + .set .Lxchal_ofs_, (.Lxchal_ofs_ & ~.Ligmask) + .endif + .endm + /* + * We could optimize for addi to expand to only addmi instead of + * "addmi;addi", where possible. Here's a partial example how: + * .set .Lmaxmask, -(\ofsalign) & -(\totalign) + * .if (((\maxofs) + ~.Lmaxmask + 1) & 0xFFFFFF00) && ((.Lxchal_ofs_ & ~.Lmaxmask) == 0) + * .set .Ligmask, 0xFFFFFF00 + * .elif ... ditto for negative ofs range ... + * .set .Ligmask, 0xFFFFFF00 + * .set ... adjust per offset ... + * .else + * .set .Ligmask, 0xFFFFFFFF + * .endif + */ + + /* Invoke this after xchal_XXX_{load,store} macros to restore \ptr. */ + .macro xchal_sa_ptr_restore ptr + .if .Lxchal_pofs_ + addi \ptr, \ptr, - .Lxchal_pofs_ + .set .Lxchal_ofs_, .Lxchal_ofs_ + .Lxchal_pofs_ + .set .Lxchal_pofs_, 0 + .endif + .endm + + /* + * Use as eg: + * xchal_atmps_store a1, SOMEOFS, XCHAL_SA_NUM_ATMPS, a4, a5 + * xchal_ncp_load a2, a0,a3,a4,a5 + * xchal_atmps_load a1, SOMEOFS, XCHAL_SA_NUM_ATMPS, a4, a5 + * + * Specify only the ARs you *haven't* saved/restored already, up to 4. + * They *must* be the *last* ARs (in same order) specified to save area + * load/store sequences. In the example above, a0 and a3 were already + * saved/restored and unused (thus available) but a4 and a5 were not. + */ +#define xchal_atmps_store xchal_atmps_loadstore s32i, +#define xchal_atmps_load xchal_atmps_loadstore l32i, + .macro xchal_atmps_loadstore inst ptr offset nreq aa=0 ab=0 ac=0 ad=0 + .set .Lnsaved_, 0 + .irp reg,\aa,\ab,\ac,\ad + .ifeq 0x\reg ; .set .Lnsaved_,.Lnsaved_+1 ; .endif + .endr + .set .Laofs_, 0 + .irp reg,\aa,\ab,\ac,\ad + .ifgt (\nreq)-.Lnsaved_ + \inst \reg, \ptr, .Laofs_+\offset + .set .Laofs_,.Laofs_+4 + .set .Lnsaved_,.Lnsaved_+1 + .endif + .endr + .endm + +/*#define xchal_ncp_load_a2 xchal_ncp_load a2,a3,a4,a5,a6*/ +/*#define xchal_ncp_store_a2 xchal_ncp_store a2,a3,a4,a5,a6*/ +#define xchal_extratie_load xchal_ncptie_load +#define xchal_extratie_store xchal_ncptie_store +#define xchal_extratie_load_a2 xchal_ncptie_load a2,a3,a4,a5,a6 +#define xchal_extratie_store_a2 xchal_ncptie_store a2,a3,a4,a5,a6 +#define xchal_extra_load xchal_ncp_load +#define xchal_extra_store xchal_ncp_store +#define xchal_extra_load_a2 xchal_ncp_load a2,a3,a4,a5,a6 +#define xchal_extra_store_a2 xchal_ncp_store a2,a3,a4,a5,a6 +#define xchal_extra_load_funcbody xchal_ncp_load a2,a3,a4,a5,a6 +#define xchal_extra_store_funcbody xchal_ncp_store a2,a3,a4,a5,a6 +#define xchal_cp0_store_a2 xchal_cp0_store a2,a3,a4,a5,a6 +#define xchal_cp0_load_a2 xchal_cp0_load a2,a3,a4,a5,a6 +#define xchal_cp1_store_a2 xchal_cp1_store a2,a3,a4,a5,a6 +#define xchal_cp1_load_a2 xchal_cp1_load a2,a3,a4,a5,a6 +#define xchal_cp2_store_a2 xchal_cp2_store a2,a3,a4,a5,a6 +#define xchal_cp2_load_a2 xchal_cp2_load a2,a3,a4,a5,a6 +#define xchal_cp3_store_a2 xchal_cp3_store a2,a3,a4,a5,a6 +#define xchal_cp3_load_a2 xchal_cp3_load a2,a3,a4,a5,a6 +#define xchal_cp4_store_a2 xchal_cp4_store a2,a3,a4,a5,a6 +#define xchal_cp4_load_a2 xchal_cp4_load a2,a3,a4,a5,a6 +#define xchal_cp5_store_a2 xchal_cp5_store a2,a3,a4,a5,a6 +#define xchal_cp5_load_a2 xchal_cp5_load a2,a3,a4,a5,a6 +#define xchal_cp6_store_a2 xchal_cp6_store a2,a3,a4,a5,a6 +#define xchal_cp6_load_a2 xchal_cp6_load a2,a3,a4,a5,a6 +#define xchal_cp7_store_a2 xchal_cp7_store a2,a3,a4,a5,a6 +#define xchal_cp7_load_a2 xchal_cp7_load a2,a3,a4,a5,a6 + +/* Empty placeholder macros for undefined coprocessors: */ +#if (XCHAL_CP_MASK & ~XCHAL_CP_PORT_MASK) == 0 +# if XCHAL_CP0_SA_SIZE == 0 + .macro xchal_cp0_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp0_load p a b c d continue=0 ofs=-1 select=-1 ; .endm +# endif +# if XCHAL_CP1_SA_SIZE == 0 + .macro xchal_cp1_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp1_load p a b c d continue=0 ofs=-1 select=-1 ; .endm +# endif +# if XCHAL_CP2_SA_SIZE == 0 + .macro xchal_cp2_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp2_load p a b c d continue=0 ofs=-1 select=-1 ; .endm +# endif +# if XCHAL_CP3_SA_SIZE == 0 + .macro xchal_cp3_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp3_load p a b c d continue=0 ofs=-1 select=-1 ; .endm +# endif +# if XCHAL_CP4_SA_SIZE == 0 + .macro xchal_cp4_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp4_load p a b c d continue=0 ofs=-1 select=-1 ; .endm +# endif +# if XCHAL_CP5_SA_SIZE == 0 + .macro xchal_cp5_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp5_load p a b c d continue=0 ofs=-1 select=-1 ; .endm +# endif +# if XCHAL_CP6_SA_SIZE == 0 + .macro xchal_cp6_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp6_load p a b c d continue=0 ofs=-1 select=-1 ; .endm +# endif +# if XCHAL_CP7_SA_SIZE == 0 + .macro xchal_cp7_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp7_load p a b c d continue=0 ofs=-1 select=-1 ; .endm +# endif +#endif + + /******************** + * Macros to create functions that save and restore the state of *any* TIE + * coprocessor (by dynamic index). + */ + + /* + * Macro that expands to the body of a function + * that stores the selected coprocessor's state (registers etc). + * Entry: a2 = ptr to save area in which to save cp state + * a3 = coprocessor number + * Exit: any register a2-a15 (?) may have been clobbered. + */ + .macro xchal_cpi_store_funcbody +#if (XCHAL_CP_MASK & ~XCHAL_CP_PORT_MASK) +# if XCHAL_CP0_SA_SIZE + bnez a3, 99f + xchal_cp0_store_a2 + j 90f +99: +# endif +# if XCHAL_CP1_SA_SIZE + bnei a3, 1, 99f + xchal_cp1_store_a2 + j 90f +99: +# endif +# if XCHAL_CP2_SA_SIZE + bnei a3, 2, 99f + xchal_cp2_store_a2 + j 90f +99: +# endif +# if XCHAL_CP3_SA_SIZE + bnei a3, 3, 99f + xchal_cp3_store_a2 + j 90f +99: +# endif +# if XCHAL_CP4_SA_SIZE + bnei a3, 4, 99f + xchal_cp4_store_a2 + j 90f +99: +# endif +# if XCHAL_CP5_SA_SIZE + bnei a3, 5, 99f + xchal_cp5_store_a2 + j 90f +99: +# endif +# if XCHAL_CP6_SA_SIZE + bnei a3, 6, 99f + xchal_cp6_store_a2 + j 90f +99: +# endif +# if XCHAL_CP7_SA_SIZE + bnei a3, 7, 99f + xchal_cp7_store_a2 + j 90f +99: +# endif +90: +#endif + .endm + + /* + * Macro that expands to the body of a function + * that loads the selected coprocessor's state (registers etc). + * Entry: a2 = ptr to save area from which to restore cp state + * a3 = coprocessor number + * Exit: any register a2-a15 (?) may have been clobbered. + */ + .macro xchal_cpi_load_funcbody +#if (XCHAL_CP_MASK & ~XCHAL_CP_PORT_MASK) +# if XCHAL_CP0_SA_SIZE + bnez a3, 99f + xchal_cp0_load_a2 + j 90f +99: +# endif +# if XCHAL_CP1_SA_SIZE + bnei a3, 1, 99f + xchal_cp1_load_a2 + j 90f +99: +# endif +# if XCHAL_CP2_SA_SIZE + bnei a3, 2, 99f + xchal_cp2_load_a2 + j 90f +99: +# endif +# if XCHAL_CP3_SA_SIZE + bnei a3, 3, 99f + xchal_cp3_load_a2 + j 90f +99: +# endif +# if XCHAL_CP4_SA_SIZE + bnei a3, 4, 99f + xchal_cp4_load_a2 + j 90f +99: +# endif +# if XCHAL_CP5_SA_SIZE + bnei a3, 5, 99f + xchal_cp5_load_a2 + j 90f +99: +# endif +# if XCHAL_CP6_SA_SIZE + bnei a3, 6, 99f + xchal_cp6_load_a2 + j 90f +99: +# endif +# if XCHAL_CP7_SA_SIZE + bnei a3, 7, 99f + xchal_cp7_load_a2 + j 90f +99: +# endif +90: +#endif + .endm + +#endif /*_ASMLANGUAGE or __ASSEMBLER__*/ + + +/* Other default macros for undefined coprocessors: */ +#ifndef XCHAL_CP0_NAME +# define XCHAL_CP0_NAME 0 +# define XCHAL_CP0_SA_CONTENTS_LIBDB_NUM 0 +# define XCHAL_CP0_SA_CONTENTS_LIBDB /* empty */ +#endif +#ifndef XCHAL_CP1_NAME +# define XCHAL_CP1_NAME 0 +# define XCHAL_CP1_SA_CONTENTS_LIBDB_NUM 0 +# define XCHAL_CP1_SA_CONTENTS_LIBDB /* empty */ +#endif +#ifndef XCHAL_CP2_NAME +# define XCHAL_CP2_NAME 0 +# define XCHAL_CP2_SA_CONTENTS_LIBDB_NUM 0 +# define XCHAL_CP2_SA_CONTENTS_LIBDB /* empty */ +#endif +#ifndef XCHAL_CP3_NAME +# define XCHAL_CP3_NAME 0 +# define XCHAL_CP3_SA_CONTENTS_LIBDB_NUM 0 +# define XCHAL_CP3_SA_CONTENTS_LIBDB /* empty */ +#endif +#ifndef XCHAL_CP4_NAME +# define XCHAL_CP4_NAME 0 +# define XCHAL_CP4_SA_CONTENTS_LIBDB_NUM 0 +# define XCHAL_CP4_SA_CONTENTS_LIBDB /* empty */ +#endif +#ifndef XCHAL_CP5_NAME +# define XCHAL_CP5_NAME 0 +# define XCHAL_CP5_SA_CONTENTS_LIBDB_NUM 0 +# define XCHAL_CP5_SA_CONTENTS_LIBDB /* empty */ +#endif +#ifndef XCHAL_CP6_NAME +# define XCHAL_CP6_NAME 0 +# define XCHAL_CP6_SA_CONTENTS_LIBDB_NUM 0 +# define XCHAL_CP6_SA_CONTENTS_LIBDB /* empty */ +#endif +#ifndef XCHAL_CP7_NAME +# define XCHAL_CP7_NAME 0 +# define XCHAL_CP7_SA_CONTENTS_LIBDB_NUM 0 +# define XCHAL_CP7_SA_CONTENTS_LIBDB /* empty */ +#endif + +#if XCHAL_CP_MASK == 0 +/* Filler info for unassigned coprocessors, to simplify arrays etc: */ +#define XCHAL_CP0_SA_SIZE 0 +#define XCHAL_CP0_SA_ALIGN 1 +#define XCHAL_CP1_SA_SIZE 0 +#define XCHAL_CP1_SA_ALIGN 1 +#define XCHAL_CP2_SA_SIZE 0 +#define XCHAL_CP2_SA_ALIGN 1 +#define XCHAL_CP3_SA_SIZE 0 +#define XCHAL_CP3_SA_ALIGN 1 +#define XCHAL_CP4_SA_SIZE 0 +#define XCHAL_CP4_SA_ALIGN 1 +#define XCHAL_CP5_SA_SIZE 0 +#define XCHAL_CP5_SA_ALIGN 1 +#define XCHAL_CP6_SA_SIZE 0 +#define XCHAL_CP6_SA_ALIGN 1 +#define XCHAL_CP7_SA_SIZE 0 +#define XCHAL_CP7_SA_ALIGN 1 +#endif + + +/* Indexing macros: */ +#define _XCHAL_CP_SA_SIZE(n) XCHAL_CP ## n ## _SA_SIZE +#define XCHAL_CP_SA_SIZE(n) _XCHAL_CP_SA_SIZE(n) /* n = 0 .. 7 */ +#define _XCHAL_CP_SA_ALIGN(n) XCHAL_CP ## n ## _SA_ALIGN +#define XCHAL_CP_SA_ALIGN(n) _XCHAL_CP_SA_ALIGN(n) /* n = 0 .. 7 */ + +#define XCHAL_CPEXTRA_SA_SIZE_TOR2 XCHAL_CPEXTRA_SA_SIZE /* Tor2Beta only - do not use */ + +/* Link-time HAL global variables that report coprocessor numbers by name + (names are case-preserved from the original TIE): */ +#if !defined(_ASMLANGUAGE) && !defined(_NOCLANGUAGE) && !defined(__ASSEMBLER__) +# define _XCJOIN(a,b) a ## b +# define XCJOIN(a,b) _XCJOIN(a,b) +# ifdef XCHAL_CP0_NAME +extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP0_IDENT); +extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP0_IDENT); +# endif +# ifdef XCHAL_CP1_NAME +extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP1_IDENT); +extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP1_IDENT); +# endif +# ifdef XCHAL_CP2_NAME +extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP2_IDENT); +extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP2_IDENT); +# endif +# ifdef XCHAL_CP3_NAME +extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP3_IDENT); +extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP3_IDENT); +# endif +# ifdef XCHAL_CP4_NAME +extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP4_IDENT); +extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP4_IDENT); +# endif +# ifdef XCHAL_CP5_NAME +extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP5_IDENT); +extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP5_IDENT); +# endif +# ifdef XCHAL_CP6_NAME +extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP6_IDENT); +extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP6_IDENT); +# endif +# ifdef XCHAL_CP7_NAME +extern const unsigned char XCJOIN(Xthal_cp_id_,XCHAL_CP7_IDENT); +extern const unsigned int XCJOIN(Xthal_cp_mask_,XCHAL_CP7_IDENT); +# endif +#endif + + + + +/*---------------------------------------------------------------------- + DERIVED + ----------------------------------------------------------------------*/ + +#if XCHAL_HAVE_BE +#define XCHAL_INST_ILLN 0xD60F /* 2-byte illegal instruction, msb-first */ +#define XCHAL_INST_ILLN_BYTE0 0xD6 /* 2-byte illegal instruction, 1st byte */ +#define XCHAL_INST_ILLN_BYTE1 0x0F /* 2-byte illegal instruction, 2nd byte */ +#else +#define XCHAL_INST_ILLN 0xF06D /* 2-byte illegal instruction, lsb-first */ +#define XCHAL_INST_ILLN_BYTE0 0x6D /* 2-byte illegal instruction, 1st byte */ +#define XCHAL_INST_ILLN_BYTE1 0xF0 /* 2-byte illegal instruction, 2nd byte */ +#endif +/* Belongs in xtensa/hal.h: */ +#define XTHAL_INST_ILL 0x000000 /* 3-byte illegal instruction */ + + +/* + * Because information as to exactly which hardware version is targeted + * by a given software build is not always available, compile-time HAL + * Hardware-Release "_AT" macros are fuzzy (return 0, 1, or XCHAL_MAYBE): + * (Here "RELEASE" is now a misnomer; these are product *versions*, not the releases + * under which they are released. In the T10##.# era there was no distinction.) + */ +#if XCHAL_HW_CONFIGID_RELIABLE +# define XCHAL_HW_RELEASE_AT_OR_BELOW(major,minor) (XTHAL_REL_LE( XCHAL_HW_VERSION_MAJOR,XCHAL_HW_VERSION_MINOR, major,minor ) ? 1 : 0) +# define XCHAL_HW_RELEASE_AT_OR_ABOVE(major,minor) (XTHAL_REL_GE( XCHAL_HW_VERSION_MAJOR,XCHAL_HW_VERSION_MINOR, major,minor ) ? 1 : 0) +# define XCHAL_HW_RELEASE_AT(major,minor) (XTHAL_REL_EQ( XCHAL_HW_VERSION_MAJOR,XCHAL_HW_VERSION_MINOR, major,minor ) ? 1 : 0) +# define XCHAL_HW_RELEASE_MAJOR_AT(major) ((XCHAL_HW_VERSION_MAJOR == (major)) ? 1 : 0) +#else +# define XCHAL_HW_RELEASE_AT_OR_BELOW(major,minor) ( ((major) < 1040 && XCHAL_HAVE_XEA2) ? 0 \ + : ((major) > 1050 && XCHAL_HAVE_XEA1) ? 1 \ + : XTHAL_MAYBE ) +# define XCHAL_HW_RELEASE_AT_OR_ABOVE(major,minor) ( ((major) >= 2000 && XCHAL_HAVE_XEA1) ? 0 \ + : (XTHAL_REL_LE(major,minor, 1040,0) && XCHAL_HAVE_XEA2) ? 1 \ + : XTHAL_MAYBE ) +# define XCHAL_HW_RELEASE_AT(major,minor) ( (((major) < 1040 && XCHAL_HAVE_XEA2) || \ + ((major) >= 2000 && XCHAL_HAVE_XEA1)) ? 0 : XTHAL_MAYBE) +# define XCHAL_HW_RELEASE_MAJOR_AT(major) XCHAL_HW_RELEASE_AT(major,0) +#endif + +/* + * Specific errata: + */ + +/* + * Erratum T1020.H13, T1030.H7, T1040.H10, T1050.H4 (fixed in T1040.3 and T1050.1; + * relevant only in XEA1, kernel-vector mode, level-one interrupts and overflows enabled): + */ +#define XCHAL_MAYHAVE_ERRATUM_XEA1KWIN (XCHAL_HAVE_XEA1 && \ + (XCHAL_HW_RELEASE_AT_OR_BELOW(1040,2) != 0 \ + || XCHAL_HW_RELEASE_AT(1050,0))) + + + +#endif /*XTENSA_CONFIG_CORE_H*/ + diff --git a/extra_include/xtensa/config/defs.h b/extra_include/xtensa/config/defs.h index d81c242b..fbf2ff6f 100644 --- a/extra_include/xtensa/config/defs.h +++ b/extra_include/xtensa/config/defs.h @@ -1,37 +1,37 @@ -/* Definitions for Xtensa instructions, types, and protos. */ - -/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 2003-2004 Tensilica Inc. - - 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. */ - -/* NOTE: This file exists only for backward compatibility with T1050 - and earlier Xtensa releases. It includes only a subset of the - available header files. */ - -#ifndef _XTENSA_BASE_HEADER -#define _XTENSA_BASE_HEADER - -#ifdef __XTENSA__ - -#include -#include - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_BASE_HEADER */ +/* Definitions for Xtensa instructions, types, and protos. */ + +/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 2003-2004 Tensilica Inc. + + 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. */ + +/* NOTE: This file exists only for backward compatibility with T1050 + and earlier Xtensa releases. It includes only a subset of the + available header files. */ + +#ifndef _XTENSA_BASE_HEADER +#define _XTENSA_BASE_HEADER + +#ifdef __XTENSA__ + +#include +#include + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_BASE_HEADER */ diff --git a/extra_include/xtensa/config/specreg.h b/extra_include/xtensa/config/specreg.h index e49ecc50..724b490d 100644 --- a/extra_include/xtensa/config/specreg.h +++ b/extra_include/xtensa/config/specreg.h @@ -1,80 +1,80 @@ -/* - * Xtensa Special Register symbolic names - */ - -/* $Id: //depot/rel/Boreal/Xtensa/SWConfig/hal/specreg.h.tpp#2 $ */ - -/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 1998-2002 Tensilica Inc. - - 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 XTENSA_SPECREG_H -#define XTENSA_SPECREG_H - -/* Include these special register bitfield definitions, for historical reasons: */ -#include - - -/* Special registers: */ -#define SAR 3 -#define LITBASE 5 -#define IBREAKENABLE 96 -#define DDR 104 -#define IBREAKA_0 128 -#define DBREAKA_0 144 -#define DBREAKC_0 160 -#define EPC_1 177 -#define EPC_2 178 -#define EPC_3 179 -#define DEPC 192 -#define EPS_2 194 -#define EPS_3 195 -#define EXCSAVE_1 209 -#define EXCSAVE_2 210 -#define EXCSAVE_3 211 -#define INTERRUPT 226 -#define INTENABLE 228 -#define PS 230 -#define VECBASE 231 -#define EXCCAUSE 232 -#define DEBUGCAUSE 233 -#define CCOUNT 234 -#define PRID 235 -#define ICOUNT 236 -#define ICOUNTLEVEL 237 -#define EXCVADDR 238 -#define CCOMPARE_0 240 - -/* Special cases (bases of special register series): */ -#define IBREAKA 128 -#define DBREAKA 144 -#define DBREAKC 160 -#define EPC 176 -#define EPS 192 -#define EXCSAVE 208 -#define CCOMPARE 240 - -/* Special names for read-only and write-only interrupt registers: */ -#define INTREAD 226 -#define INTSET 226 -#define INTCLEAR 227 - -#endif /* XTENSA_SPECREG_H */ - +/* + * Xtensa Special Register symbolic names + */ + +/* $Id: //depot/rel/Boreal/Xtensa/SWConfig/hal/specreg.h.tpp#2 $ */ + +/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 1998-2002 Tensilica Inc. + + 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 XTENSA_SPECREG_H +#define XTENSA_SPECREG_H + +/* Include these special register bitfield definitions, for historical reasons: */ +#include + + +/* Special registers: */ +#define SAR 3 +#define LITBASE 5 +#define IBREAKENABLE 96 +#define DDR 104 +#define IBREAKA_0 128 +#define DBREAKA_0 144 +#define DBREAKC_0 160 +#define EPC_1 177 +#define EPC_2 178 +#define EPC_3 179 +#define DEPC 192 +#define EPS_2 194 +#define EPS_3 195 +#define EXCSAVE_1 209 +#define EXCSAVE_2 210 +#define EXCSAVE_3 211 +#define INTERRUPT 226 +#define INTENABLE 228 +#define PS 230 +#define VECBASE 231 +#define EXCCAUSE 232 +#define DEBUGCAUSE 233 +#define CCOUNT 234 +#define PRID 235 +#define ICOUNT 236 +#define ICOUNTLEVEL 237 +#define EXCVADDR 238 +#define CCOMPARE_0 240 + +/* Special cases (bases of special register series): */ +#define IBREAKA 128 +#define DBREAKA 144 +#define DBREAKC 160 +#define EPC 176 +#define EPS 192 +#define EXCSAVE 208 +#define CCOMPARE 240 + +/* Special names for read-only and write-only interrupt registers: */ +#define INTREAD 226 +#define INTSET 226 +#define INTCLEAR 227 + +#endif /* XTENSA_SPECREG_H */ + diff --git a/extra_include/xtensa/config/system.h b/extra_include/xtensa/config/system.h index 9d16ce52..7a4ac1dc 100644 --- a/extra_include/xtensa/config/system.h +++ b/extra_include/xtensa/config/system.h @@ -1,252 +1,252 @@ -/* - * xtensa/config/system.h -- HAL definitions that are dependent on SYSTEM configuration - * - * NOTE: The location and contents of this file are highly subject to change. - * - * Source for configuration-independent binaries (which link in a - * configuration-specific HAL library) must NEVER include this file. - * The HAL itself has historically included this file in some instances, - * but this is not appropriate either, because the HAL is meant to be - * core-specific but system independent. - */ - -/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 2000-2007 Tensilica Inc. - - 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 XTENSA_CONFIG_SYSTEM_H -#define XTENSA_CONFIG_SYSTEM_H - -/*#include */ - - - -/*---------------------------------------------------------------------- - CONFIGURED SOFTWARE OPTIONS - ----------------------------------------------------------------------*/ - -#define XSHAL_USE_ABSOLUTE_LITERALS 0 /* (sw-only option, whether software uses absolute literals) */ - -#define XSHAL_ABI XTHAL_ABI_CALL0 /* (sw-only option, selected ABI) */ -/* The above maps to one of the following constants: */ -#define XTHAL_ABI_WINDOWED 0 -#define XTHAL_ABI_CALL0 1 -/* Alternatives: */ -/*#define XSHAL_WINDOWED_ABI 0*/ /* set if windowed ABI selected */ -/*#define XSHAL_CALL0_ABI 1*/ /* set if call0 ABI selected */ - -#define XSHAL_CLIB XTHAL_CLIB_NEWLIB /* (sw-only option, selected C library) */ -/* The above maps to one of the following constants: */ -#define XTHAL_CLIB_NEWLIB 0 -#define XTHAL_CLIB_UCLIBC 1 -/* Alternatives: */ -/*#define XSHAL_NEWLIB 1*/ /* set if newlib C library selected */ -/*#define XSHAL_UCLIBC 0*/ /* set if uCLibC C library selected */ - -#define XSHAL_USE_FLOATING_POINT 1 - -/*---------------------------------------------------------------------- - DEVICE ADDRESSES - ----------------------------------------------------------------------*/ - -/* - * Strange place to find these, but the configuration GUI - * allows moving these around to account for various core - * configurations. Specific boards (and their BSP software) - * will have specific meanings for these components. - */ - -/* I/O Block areas: */ -#define XSHAL_IOBLOCK_CACHED_VADDR 0x70000000 -#define XSHAL_IOBLOCK_CACHED_PADDR 0x70000000 -#define XSHAL_IOBLOCK_CACHED_SIZE 0x0E000000 - -#define XSHAL_IOBLOCK_BYPASS_VADDR 0x90000000 -#define XSHAL_IOBLOCK_BYPASS_PADDR 0x90000000 -#define XSHAL_IOBLOCK_BYPASS_SIZE 0x0E000000 - -/* System ROM: */ -#define XSHAL_ROM_VADDR 0x50000000 -#define XSHAL_ROM_PADDR 0x50000000 -#define XSHAL_ROM_SIZE 0x01000000 -/* Largest available area (free of vectors): */ -#define XSHAL_ROM_AVAIL_VADDR 0x50000300 -#define XSHAL_ROM_AVAIL_VSIZE 0x00FFFD00 - -/* System RAM: */ -#define XSHAL_RAM_VADDR 0x60000000 -#define XSHAL_RAM_PADDR 0x60000000 -#define XSHAL_RAM_VSIZE 0x04000000 -#define XSHAL_RAM_PSIZE 0x04000000 -#define XSHAL_RAM_SIZE XSHAL_RAM_PSIZE -/* Largest available area (free of vectors): */ -#define XSHAL_RAM_AVAIL_VADDR 0x60000000 -#define XSHAL_RAM_AVAIL_VSIZE 0x04000000 - -/* - * Shadow system RAM (same device as system RAM, at different address). - * (Emulation boards need this for the SONIC Ethernet driver - * when data caches are configured for writeback mode.) - * NOTE: on full MMU configs, this points to the BYPASS virtual address - * of system RAM, ie. is the same as XSHAL_RAM_* except that virtual - * addresses are viewed through the BYPASS static map rather than - * the CACHED static map. - */ -#define XSHAL_RAM_BYPASS_VADDR 0xA0000000 -#define XSHAL_RAM_BYPASS_PADDR 0xA0000000 -#define XSHAL_RAM_BYPASS_PSIZE 0x04000000 - -/* Alternate system RAM (different device than system RAM): */ -/*#define XSHAL_ALTRAM_[VP]ADDR ...not configured...*/ -/*#define XSHAL_ALTRAM_SIZE ...not configured...*/ - -/* Some available location in which to place devices in a simulation (eg. XTMP): */ -#define XSHAL_SIMIO_CACHED_VADDR 0xC0000000 -#define XSHAL_SIMIO_BYPASS_VADDR 0xC0000000 -#define XSHAL_SIMIO_PADDR 0xC0000000 -#define XSHAL_SIMIO_SIZE 0x20000000 - - -/*---------------------------------------------------------------------- - * DEVICE-ADDRESS DEPENDENT... - * - * Values written to CACHEATTR special register (or its equivalent) - * to enable and disable caches in various modes. - *----------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------- - BACKWARD COMPATIBILITY ... - ----------------------------------------------------------------------*/ - -/* - * NOTE: the following two macros are DEPRECATED. Use the latter - * board-specific macros instead, which are specially tuned for the - * particular target environments' memory maps. - */ -#define XSHAL_CACHEATTR_BYPASS XSHAL_XT2000_CACHEATTR_BYPASS /* disable caches in bypass mode */ -#define XSHAL_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_DEFAULT /* default setting to enable caches (no writeback!) */ - -/*---------------------------------------------------------------------- - GENERIC - ----------------------------------------------------------------------*/ - -/* For the following, a 512MB region is used if it contains a system (PIF) RAM, - * system (PIF) ROM, local memory, or XLMI. */ - -/* These set any unused 512MB region to cache-BYPASS attribute: */ -#define XSHAL_ALLVALID_CACHEATTR_WRITEBACK 0x22221112 /* enable caches in write-back mode */ -#define XSHAL_ALLVALID_CACHEATTR_WRITEALLOC 0x22221112 /* enable caches in write-allocate mode */ -#define XSHAL_ALLVALID_CACHEATTR_WRITETHRU 0x22221112 /* enable caches in write-through mode */ -#define XSHAL_ALLVALID_CACHEATTR_BYPASS 0x22222222 /* disable caches in bypass mode */ -#define XSHAL_ALLVALID_CACHEATTR_DEFAULT XSHAL_ALLVALID_CACHEATTR_WRITEBACK /* default setting to enable caches */ - -/* These set any unused 512MB region to ILLEGAL attribute: */ -#define XSHAL_STRICT_CACHEATTR_WRITEBACK 0xFFFF111F /* enable caches in write-back mode */ -#define XSHAL_STRICT_CACHEATTR_WRITEALLOC 0xFFFF111F /* enable caches in write-allocate mode */ -#define XSHAL_STRICT_CACHEATTR_WRITETHRU 0xFFFF111F /* enable caches in write-through mode */ -#define XSHAL_STRICT_CACHEATTR_BYPASS 0xFFFF222F /* disable caches in bypass mode */ -#define XSHAL_STRICT_CACHEATTR_DEFAULT XSHAL_STRICT_CACHEATTR_WRITEBACK /* default setting to enable caches */ - -/* These set the first 512MB, if unused, to ILLEGAL attribute to help catch - * NULL-pointer dereference bugs; all other unused 512MB regions are set - * to cache-BYPASS attribute: */ -#define XSHAL_TRAPNULL_CACHEATTR_WRITEBACK 0x2222111F /* enable caches in write-back mode */ -#define XSHAL_TRAPNULL_CACHEATTR_WRITEALLOC 0x2222111F /* enable caches in write-allocate mode */ -#define XSHAL_TRAPNULL_CACHEATTR_WRITETHRU 0x2222111F /* enable caches in write-through mode */ -#define XSHAL_TRAPNULL_CACHEATTR_BYPASS 0x2222222F /* disable caches in bypass mode */ -#define XSHAL_TRAPNULL_CACHEATTR_DEFAULT XSHAL_TRAPNULL_CACHEATTR_WRITEBACK /* default setting to enable caches */ - -/*---------------------------------------------------------------------- - ISS (Instruction Set Simulator) SPECIFIC ... - ----------------------------------------------------------------------*/ - -/* For now, ISS defaults to the TRAPNULL settings: */ -#define XSHAL_ISS_CACHEATTR_WRITEBACK XSHAL_TRAPNULL_CACHEATTR_WRITEBACK -#define XSHAL_ISS_CACHEATTR_WRITEALLOC XSHAL_TRAPNULL_CACHEATTR_WRITEALLOC -#define XSHAL_ISS_CACHEATTR_WRITETHRU XSHAL_TRAPNULL_CACHEATTR_WRITETHRU -#define XSHAL_ISS_CACHEATTR_BYPASS XSHAL_TRAPNULL_CACHEATTR_BYPASS -#define XSHAL_ISS_CACHEATTR_DEFAULT XSHAL_TRAPNULL_CACHEATTR_WRITEBACK - -#define XSHAL_ISS_PIPE_REGIONS 0 -#define XSHAL_ISS_SDRAM_REGIONS 0 - - -/*---------------------------------------------------------------------- - XT2000 BOARD SPECIFIC ... - ----------------------------------------------------------------------*/ - -/* For the following, a 512MB region is used if it contains any system RAM, - * system ROM, local memory, XLMI, or other XT2000 board device or memory. - * Regions containing devices are forced to cache-BYPASS mode regardless - * of whether the macro is _WRITEBACK vs. _BYPASS etc. */ - -/* These set any 512MB region unused on the XT2000 to ILLEGAL attribute: */ -#define XSHAL_XT2000_CACHEATTR_WRITEBACK 0xFF22111F /* enable caches in write-back mode */ -#define XSHAL_XT2000_CACHEATTR_WRITEALLOC 0xFF22111F /* enable caches in write-allocate mode */ -#define XSHAL_XT2000_CACHEATTR_WRITETHRU 0xFF22111F /* enable caches in write-through mode */ -#define XSHAL_XT2000_CACHEATTR_BYPASS 0xFF22222F /* disable caches in bypass mode */ -#define XSHAL_XT2000_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_WRITEBACK /* default setting to enable caches */ - -#define XSHAL_XT2000_PIPE_REGIONS 0x00000000 /* BusInt pipeline regions */ -#define XSHAL_XT2000_SDRAM_REGIONS 0x00000440 /* BusInt SDRAM regions */ - - -/*---------------------------------------------------------------------- - VECTOR INFO AND SIZES - ----------------------------------------------------------------------*/ - -#define XSHAL_VECTORS_PACKED 0 -#define XSHAL_STATIC_VECTOR_SELECT 0 -#define XSHAL_RESET_VECTOR_VADDR 0x50000000 -#define XSHAL_RESET_VECTOR_PADDR 0x50000000 - -/* - * Sizes allocated to vectors by the system (memory map) configuration. - * These sizes are constrained by core configuration (eg. one vector's - * code cannot overflow into another vector) but are dependent on the - * system or board (or LSP) memory map configuration. - * - * Whether or not each vector happens to be in a system ROM is also - * a system configuration matter, sometimes useful, included here also: - */ -#define XSHAL_RESET_VECTOR_SIZE 0x00000300 -#define XSHAL_RESET_VECTOR_ISROM 1 -#define XSHAL_USER_VECTOR_SIZE 0x0000001C -#define XSHAL_USER_VECTOR_ISROM 0 -#define XSHAL_PROGRAMEXC_VECTOR_SIZE XSHAL_USER_VECTOR_SIZE /* for backward compatibility */ -#define XSHAL_USEREXC_VECTOR_SIZE XSHAL_USER_VECTOR_SIZE /* for backward compatibility */ -#define XSHAL_KERNEL_VECTOR_SIZE 0x0000001C -#define XSHAL_KERNEL_VECTOR_ISROM 0 -#define XSHAL_STACKEDEXC_VECTOR_SIZE XSHAL_KERNEL_VECTOR_SIZE /* for backward compatibility */ -#define XSHAL_KERNELEXC_VECTOR_SIZE XSHAL_KERNEL_VECTOR_SIZE /* for backward compatibility */ -#define XSHAL_DOUBLEEXC_VECTOR_SIZE 0x00000010 -#define XSHAL_DOUBLEEXC_VECTOR_ISROM 0 -#define XSHAL_INTLEVEL2_VECTOR_SIZE 0x0000000C -#define XSHAL_INTLEVEL2_VECTOR_ISROM 0 -#define XSHAL_DEBUG_VECTOR_SIZE XSHAL_INTLEVEL2_VECTOR_SIZE -#define XSHAL_DEBUG_VECTOR_ISROM XSHAL_INTLEVEL2_VECTOR_ISROM -#define XSHAL_NMI_VECTOR_SIZE 0x0000000C -#define XSHAL_NMI_VECTOR_ISROM 0 -#define XSHAL_INTLEVEL3_VECTOR_SIZE XSHAL_NMI_VECTOR_SIZE - - -#endif /*XTENSA_CONFIG_SYSTEM_H*/ - +/* + * xtensa/config/system.h -- HAL definitions that are dependent on SYSTEM configuration + * + * NOTE: The location and contents of this file are highly subject to change. + * + * Source for configuration-independent binaries (which link in a + * configuration-specific HAL library) must NEVER include this file. + * The HAL itself has historically included this file in some instances, + * but this is not appropriate either, because the HAL is meant to be + * core-specific but system independent. + */ + +/* Customer ID=7011; Build=0x2b6f6; Copyright (c) 2000-2007 Tensilica Inc. + + 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 XTENSA_CONFIG_SYSTEM_H +#define XTENSA_CONFIG_SYSTEM_H + +/*#include */ + + + +/*---------------------------------------------------------------------- + CONFIGURED SOFTWARE OPTIONS + ----------------------------------------------------------------------*/ + +#define XSHAL_USE_ABSOLUTE_LITERALS 0 /* (sw-only option, whether software uses absolute literals) */ + +#define XSHAL_ABI XTHAL_ABI_CALL0 /* (sw-only option, selected ABI) */ +/* The above maps to one of the following constants: */ +#define XTHAL_ABI_WINDOWED 0 +#define XTHAL_ABI_CALL0 1 +/* Alternatives: */ +/*#define XSHAL_WINDOWED_ABI 0*/ /* set if windowed ABI selected */ +/*#define XSHAL_CALL0_ABI 1*/ /* set if call0 ABI selected */ + +#define XSHAL_CLIB XTHAL_CLIB_NEWLIB /* (sw-only option, selected C library) */ +/* The above maps to one of the following constants: */ +#define XTHAL_CLIB_NEWLIB 0 +#define XTHAL_CLIB_UCLIBC 1 +/* Alternatives: */ +/*#define XSHAL_NEWLIB 1*/ /* set if newlib C library selected */ +/*#define XSHAL_UCLIBC 0*/ /* set if uCLibC C library selected */ + +#define XSHAL_USE_FLOATING_POINT 1 + +/*---------------------------------------------------------------------- + DEVICE ADDRESSES + ----------------------------------------------------------------------*/ + +/* + * Strange place to find these, but the configuration GUI + * allows moving these around to account for various core + * configurations. Specific boards (and their BSP software) + * will have specific meanings for these components. + */ + +/* I/O Block areas: */ +#define XSHAL_IOBLOCK_CACHED_VADDR 0x70000000 +#define XSHAL_IOBLOCK_CACHED_PADDR 0x70000000 +#define XSHAL_IOBLOCK_CACHED_SIZE 0x0E000000 + +#define XSHAL_IOBLOCK_BYPASS_VADDR 0x90000000 +#define XSHAL_IOBLOCK_BYPASS_PADDR 0x90000000 +#define XSHAL_IOBLOCK_BYPASS_SIZE 0x0E000000 + +/* System ROM: */ +#define XSHAL_ROM_VADDR 0x50000000 +#define XSHAL_ROM_PADDR 0x50000000 +#define XSHAL_ROM_SIZE 0x01000000 +/* Largest available area (free of vectors): */ +#define XSHAL_ROM_AVAIL_VADDR 0x50000300 +#define XSHAL_ROM_AVAIL_VSIZE 0x00FFFD00 + +/* System RAM: */ +#define XSHAL_RAM_VADDR 0x60000000 +#define XSHAL_RAM_PADDR 0x60000000 +#define XSHAL_RAM_VSIZE 0x04000000 +#define XSHAL_RAM_PSIZE 0x04000000 +#define XSHAL_RAM_SIZE XSHAL_RAM_PSIZE +/* Largest available area (free of vectors): */ +#define XSHAL_RAM_AVAIL_VADDR 0x60000000 +#define XSHAL_RAM_AVAIL_VSIZE 0x04000000 + +/* + * Shadow system RAM (same device as system RAM, at different address). + * (Emulation boards need this for the SONIC Ethernet driver + * when data caches are configured for writeback mode.) + * NOTE: on full MMU configs, this points to the BYPASS virtual address + * of system RAM, ie. is the same as XSHAL_RAM_* except that virtual + * addresses are viewed through the BYPASS static map rather than + * the CACHED static map. + */ +#define XSHAL_RAM_BYPASS_VADDR 0xA0000000 +#define XSHAL_RAM_BYPASS_PADDR 0xA0000000 +#define XSHAL_RAM_BYPASS_PSIZE 0x04000000 + +/* Alternate system RAM (different device than system RAM): */ +/*#define XSHAL_ALTRAM_[VP]ADDR ...not configured...*/ +/*#define XSHAL_ALTRAM_SIZE ...not configured...*/ + +/* Some available location in which to place devices in a simulation (eg. XTMP): */ +#define XSHAL_SIMIO_CACHED_VADDR 0xC0000000 +#define XSHAL_SIMIO_BYPASS_VADDR 0xC0000000 +#define XSHAL_SIMIO_PADDR 0xC0000000 +#define XSHAL_SIMIO_SIZE 0x20000000 + + +/*---------------------------------------------------------------------- + * DEVICE-ADDRESS DEPENDENT... + * + * Values written to CACHEATTR special register (or its equivalent) + * to enable and disable caches in various modes. + *----------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------- + BACKWARD COMPATIBILITY ... + ----------------------------------------------------------------------*/ + +/* + * NOTE: the following two macros are DEPRECATED. Use the latter + * board-specific macros instead, which are specially tuned for the + * particular target environments' memory maps. + */ +#define XSHAL_CACHEATTR_BYPASS XSHAL_XT2000_CACHEATTR_BYPASS /* disable caches in bypass mode */ +#define XSHAL_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_DEFAULT /* default setting to enable caches (no writeback!) */ + +/*---------------------------------------------------------------------- + GENERIC + ----------------------------------------------------------------------*/ + +/* For the following, a 512MB region is used if it contains a system (PIF) RAM, + * system (PIF) ROM, local memory, or XLMI. */ + +/* These set any unused 512MB region to cache-BYPASS attribute: */ +#define XSHAL_ALLVALID_CACHEATTR_WRITEBACK 0x22221112 /* enable caches in write-back mode */ +#define XSHAL_ALLVALID_CACHEATTR_WRITEALLOC 0x22221112 /* enable caches in write-allocate mode */ +#define XSHAL_ALLVALID_CACHEATTR_WRITETHRU 0x22221112 /* enable caches in write-through mode */ +#define XSHAL_ALLVALID_CACHEATTR_BYPASS 0x22222222 /* disable caches in bypass mode */ +#define XSHAL_ALLVALID_CACHEATTR_DEFAULT XSHAL_ALLVALID_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +/* These set any unused 512MB region to ILLEGAL attribute: */ +#define XSHAL_STRICT_CACHEATTR_WRITEBACK 0xFFFF111F /* enable caches in write-back mode */ +#define XSHAL_STRICT_CACHEATTR_WRITEALLOC 0xFFFF111F /* enable caches in write-allocate mode */ +#define XSHAL_STRICT_CACHEATTR_WRITETHRU 0xFFFF111F /* enable caches in write-through mode */ +#define XSHAL_STRICT_CACHEATTR_BYPASS 0xFFFF222F /* disable caches in bypass mode */ +#define XSHAL_STRICT_CACHEATTR_DEFAULT XSHAL_STRICT_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +/* These set the first 512MB, if unused, to ILLEGAL attribute to help catch + * NULL-pointer dereference bugs; all other unused 512MB regions are set + * to cache-BYPASS attribute: */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITEBACK 0x2222111F /* enable caches in write-back mode */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITEALLOC 0x2222111F /* enable caches in write-allocate mode */ +#define XSHAL_TRAPNULL_CACHEATTR_WRITETHRU 0x2222111F /* enable caches in write-through mode */ +#define XSHAL_TRAPNULL_CACHEATTR_BYPASS 0x2222222F /* disable caches in bypass mode */ +#define XSHAL_TRAPNULL_CACHEATTR_DEFAULT XSHAL_TRAPNULL_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +/*---------------------------------------------------------------------- + ISS (Instruction Set Simulator) SPECIFIC ... + ----------------------------------------------------------------------*/ + +/* For now, ISS defaults to the TRAPNULL settings: */ +#define XSHAL_ISS_CACHEATTR_WRITEBACK XSHAL_TRAPNULL_CACHEATTR_WRITEBACK +#define XSHAL_ISS_CACHEATTR_WRITEALLOC XSHAL_TRAPNULL_CACHEATTR_WRITEALLOC +#define XSHAL_ISS_CACHEATTR_WRITETHRU XSHAL_TRAPNULL_CACHEATTR_WRITETHRU +#define XSHAL_ISS_CACHEATTR_BYPASS XSHAL_TRAPNULL_CACHEATTR_BYPASS +#define XSHAL_ISS_CACHEATTR_DEFAULT XSHAL_TRAPNULL_CACHEATTR_WRITEBACK + +#define XSHAL_ISS_PIPE_REGIONS 0 +#define XSHAL_ISS_SDRAM_REGIONS 0 + + +/*---------------------------------------------------------------------- + XT2000 BOARD SPECIFIC ... + ----------------------------------------------------------------------*/ + +/* For the following, a 512MB region is used if it contains any system RAM, + * system ROM, local memory, XLMI, or other XT2000 board device or memory. + * Regions containing devices are forced to cache-BYPASS mode regardless + * of whether the macro is _WRITEBACK vs. _BYPASS etc. */ + +/* These set any 512MB region unused on the XT2000 to ILLEGAL attribute: */ +#define XSHAL_XT2000_CACHEATTR_WRITEBACK 0xFF22111F /* enable caches in write-back mode */ +#define XSHAL_XT2000_CACHEATTR_WRITEALLOC 0xFF22111F /* enable caches in write-allocate mode */ +#define XSHAL_XT2000_CACHEATTR_WRITETHRU 0xFF22111F /* enable caches in write-through mode */ +#define XSHAL_XT2000_CACHEATTR_BYPASS 0xFF22222F /* disable caches in bypass mode */ +#define XSHAL_XT2000_CACHEATTR_DEFAULT XSHAL_XT2000_CACHEATTR_WRITEBACK /* default setting to enable caches */ + +#define XSHAL_XT2000_PIPE_REGIONS 0x00000000 /* BusInt pipeline regions */ +#define XSHAL_XT2000_SDRAM_REGIONS 0x00000440 /* BusInt SDRAM regions */ + + +/*---------------------------------------------------------------------- + VECTOR INFO AND SIZES + ----------------------------------------------------------------------*/ + +#define XSHAL_VECTORS_PACKED 0 +#define XSHAL_STATIC_VECTOR_SELECT 0 +#define XSHAL_RESET_VECTOR_VADDR 0x50000000 +#define XSHAL_RESET_VECTOR_PADDR 0x50000000 + +/* + * Sizes allocated to vectors by the system (memory map) configuration. + * These sizes are constrained by core configuration (eg. one vector's + * code cannot overflow into another vector) but are dependent on the + * system or board (or LSP) memory map configuration. + * + * Whether or not each vector happens to be in a system ROM is also + * a system configuration matter, sometimes useful, included here also: + */ +#define XSHAL_RESET_VECTOR_SIZE 0x00000300 +#define XSHAL_RESET_VECTOR_ISROM 1 +#define XSHAL_USER_VECTOR_SIZE 0x0000001C +#define XSHAL_USER_VECTOR_ISROM 0 +#define XSHAL_PROGRAMEXC_VECTOR_SIZE XSHAL_USER_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_USEREXC_VECTOR_SIZE XSHAL_USER_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_KERNEL_VECTOR_SIZE 0x0000001C +#define XSHAL_KERNEL_VECTOR_ISROM 0 +#define XSHAL_STACKEDEXC_VECTOR_SIZE XSHAL_KERNEL_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_KERNELEXC_VECTOR_SIZE XSHAL_KERNEL_VECTOR_SIZE /* for backward compatibility */ +#define XSHAL_DOUBLEEXC_VECTOR_SIZE 0x00000010 +#define XSHAL_DOUBLEEXC_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL2_VECTOR_SIZE 0x0000000C +#define XSHAL_INTLEVEL2_VECTOR_ISROM 0 +#define XSHAL_DEBUG_VECTOR_SIZE XSHAL_INTLEVEL2_VECTOR_SIZE +#define XSHAL_DEBUG_VECTOR_ISROM XSHAL_INTLEVEL2_VECTOR_ISROM +#define XSHAL_NMI_VECTOR_SIZE 0x0000000C +#define XSHAL_NMI_VECTOR_ISROM 0 +#define XSHAL_INTLEVEL3_VECTOR_SIZE XSHAL_NMI_VECTOR_SIZE + + +#endif /*XTENSA_CONFIG_SYSTEM_H*/ + diff --git a/extra_include/xtensa/config/tie-asm.h b/extra_include/xtensa/config/tie-asm.h index 854aa17a..a83e1b39 100644 --- a/extra_include/xtensa/config/tie-asm.h +++ b/extra_include/xtensa/config/tie-asm.h @@ -1,77 +1,77 @@ -/* - * tie-asm.h -- compile-time HAL assembler definitions dependent on CORE & TIE - * - * NOTE: This header file is not meant to be included directly. - */ - -/* This header file contains assembly-language definitions (assembly - macros, etc.) for this specific Xtensa processor's TIE extensions - and options. It is customized to this Xtensa processor configuration. - - Customer ID=7011; Build=0x2b6f6; Copyright (c) 1999-2010 Tensilica Inc. - - 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 _XTENSA_CORE_TIE_ASM_H -#define _XTENSA_CORE_TIE_ASM_H - -/* Selection parameter values for save-area save/restore macros: */ -/* Option vs. TIE: */ -#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */ -#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */ -/* Whether used automatically by compiler: */ -#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */ -#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */ -/* ABI handling across function calls: */ -#define XTHAL_SAS_CALR 0x0010 /* caller-saved */ -#define XTHAL_SAS_CALE 0x0020 /* callee-saved */ -#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */ -/* Misc */ -#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */ - - - -/* Macro to save all non-coprocessor (extra) custom TIE and optional state - * (not including zero-overhead loop registers). - * Save area ptr (clobbered): ptr (1 byte aligned) - * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) - */ - .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL - xchal_sa_start \continue, \ofs - .endm // xchal_ncp_store - -/* Macro to save all non-coprocessor (extra) custom TIE and optional state - * (not including zero-overhead loop registers). - * Save area ptr (clobbered): ptr (1 byte aligned) - * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) - */ - .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL - xchal_sa_start \continue, \ofs - .endm // xchal_ncp_load - - - -#define XCHAL_NCP_NUM_ATMPS 0 - - -#define XCHAL_SA_NUM_ATMPS 0 - -#endif /*_XTENSA_CORE_TIE_ASM_H*/ - +/* + * tie-asm.h -- compile-time HAL assembler definitions dependent on CORE & TIE + * + * NOTE: This header file is not meant to be included directly. + */ + +/* This header file contains assembly-language definitions (assembly + macros, etc.) for this specific Xtensa processor's TIE extensions + and options. It is customized to this Xtensa processor configuration. + + Customer ID=7011; Build=0x2b6f6; Copyright (c) 1999-2010 Tensilica Inc. + + 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 _XTENSA_CORE_TIE_ASM_H +#define _XTENSA_CORE_TIE_ASM_H + +/* Selection parameter values for save-area save/restore macros: */ +/* Option vs. TIE: */ +#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */ +#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */ +/* Whether used automatically by compiler: */ +#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */ +#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */ +/* ABI handling across function calls: */ +#define XTHAL_SAS_CALR 0x0010 /* caller-saved */ +#define XTHAL_SAS_CALE 0x0020 /* callee-saved */ +#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */ +/* Misc */ +#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */ + + + +/* Macro to save all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Save area ptr (clobbered): ptr (1 byte aligned) + * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) + */ + .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL + xchal_sa_start \continue, \ofs + .endm // xchal_ncp_store + +/* Macro to save all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Save area ptr (clobbered): ptr (1 byte aligned) + * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) + */ + .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL + xchal_sa_start \continue, \ofs + .endm // xchal_ncp_load + + + +#define XCHAL_NCP_NUM_ATMPS 0 + + +#define XCHAL_SA_NUM_ATMPS 0 + +#endif /*_XTENSA_CORE_TIE_ASM_H*/ + diff --git a/extra_include/xtensa/config/tie.h b/extra_include/xtensa/config/tie.h index e2a30f1d..a7376074 100644 --- a/extra_include/xtensa/config/tie.h +++ b/extra_include/xtensa/config/tie.h @@ -1,119 +1,119 @@ -/* - * tie.h -- compile-time HAL definitions dependent on CORE & TIE configuration - * - * NOTE: This header file is not meant to be included directly. - */ - -/* This header file describes this specific Xtensa processor's TIE extensions - that extend basic Xtensa core functionality. It is customized to this - Xtensa processor configuration. - - Customer ID=7011; Build=0x2b6f6; Copyright (c) 1999-2010 Tensilica Inc. - - 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 _XTENSA_CORE_TIE_H -#define _XTENSA_CORE_TIE_H - -#define XCHAL_CP_NUM 0 /* number of coprocessors */ -#define XCHAL_CP_MAX 0 /* max CP ID + 1 (0 if none) */ -#define XCHAL_CP_MASK 0x00 /* bitmask of all CPs by ID */ -#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */ - -/* Save area for non-coprocessor optional and custom (TIE) state: */ -#define XCHAL_NCP_SA_SIZE 0 -#define XCHAL_NCP_SA_ALIGN 1 - -/* Total save area for optional and custom state (NCP + CPn): */ -#define XCHAL_TOTAL_SA_SIZE 0 /* with 16-byte align padding */ -#define XCHAL_TOTAL_SA_ALIGN 1 /* actual minimum alignment */ - -/* - * Detailed contents of save areas. - * NOTE: caller must define the XCHAL_SA_REG macro (not defined here) - * before expanding the XCHAL_xxx_SA_LIST() macros. - * - * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize, - * dbnum,base,regnum,bitsz,gapsz,reset,x...) - * - * s = passed from XCHAL_*_LIST(s), eg. to select how to expand - * ccused = set if used by compiler without special options or code - * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global) - * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg) - * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg) - * name = lowercase reg name (no quotes) - * galign = group byte alignment (power of 2) (galign >= align) - * align = register byte alignment (power of 2) - * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz) - * (not including any pad bytes required to galign this or next reg) - * dbnum = unique target number f/debug (see ) - * base = reg shortname w/o index (or sr=special, ur=TIE user reg) - * regnum = reg index in regfile, or special/TIE-user reg number - * bitsz = number of significant bits (regfile width, or ur/sr mask bits) - * gapsz = intervening bits, if bitsz bits not stored contiguously - * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize) - * reset = register reset value (or 0 if undefined at reset) - * x = reserved for future use (0 until then) - * - * To filter out certain registers, e.g. to expand only the non-global - * registers used by the compiler, you can do something like this: - * - * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p) - * #define SELCC0(p...) - * #define SELCC1(abikind,p...) SELAK##abikind(p) - * #define SELAK0(p...) REG(p) - * #define SELAK1(p...) REG(p) - * #define SELAK2(p...) - * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \ - * ...what you want to expand... - */ - -#define XCHAL_NCP_SA_NUM 0 -#define XCHAL_NCP_SA_LIST(s) /* empty */ - -#define XCHAL_CP0_SA_NUM 0 -#define XCHAL_CP0_SA_LIST(s) /* empty */ - -#define XCHAL_CP1_SA_NUM 0 -#define XCHAL_CP1_SA_LIST(s) /* empty */ - -#define XCHAL_CP2_SA_NUM 0 -#define XCHAL_CP2_SA_LIST(s) /* empty */ - -#define XCHAL_CP3_SA_NUM 0 -#define XCHAL_CP3_SA_LIST(s) /* empty */ - -#define XCHAL_CP4_SA_NUM 0 -#define XCHAL_CP4_SA_LIST(s) /* empty */ - -#define XCHAL_CP5_SA_NUM 0 -#define XCHAL_CP5_SA_LIST(s) /* empty */ - -#define XCHAL_CP6_SA_NUM 0 -#define XCHAL_CP6_SA_LIST(s) /* empty */ - -#define XCHAL_CP7_SA_NUM 0 -#define XCHAL_CP7_SA_LIST(s) /* empty */ - -/* Byte length of instruction from its first nibble (op0 field), per FLIX. */ -#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3 - -#endif /*_XTENSA_CORE_TIE_H*/ - +/* + * tie.h -- compile-time HAL definitions dependent on CORE & TIE configuration + * + * NOTE: This header file is not meant to be included directly. + */ + +/* This header file describes this specific Xtensa processor's TIE extensions + that extend basic Xtensa core functionality. It is customized to this + Xtensa processor configuration. + + Customer ID=7011; Build=0x2b6f6; Copyright (c) 1999-2010 Tensilica Inc. + + 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 _XTENSA_CORE_TIE_H +#define _XTENSA_CORE_TIE_H + +#define XCHAL_CP_NUM 0 /* number of coprocessors */ +#define XCHAL_CP_MAX 0 /* max CP ID + 1 (0 if none) */ +#define XCHAL_CP_MASK 0x00 /* bitmask of all CPs by ID */ +#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */ + +/* Save area for non-coprocessor optional and custom (TIE) state: */ +#define XCHAL_NCP_SA_SIZE 0 +#define XCHAL_NCP_SA_ALIGN 1 + +/* Total save area for optional and custom state (NCP + CPn): */ +#define XCHAL_TOTAL_SA_SIZE 0 /* with 16-byte align padding */ +#define XCHAL_TOTAL_SA_ALIGN 1 /* actual minimum alignment */ + +/* + * Detailed contents of save areas. + * NOTE: caller must define the XCHAL_SA_REG macro (not defined here) + * before expanding the XCHAL_xxx_SA_LIST() macros. + * + * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize, + * dbnum,base,regnum,bitsz,gapsz,reset,x...) + * + * s = passed from XCHAL_*_LIST(s), eg. to select how to expand + * ccused = set if used by compiler without special options or code + * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global) + * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg) + * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg) + * name = lowercase reg name (no quotes) + * galign = group byte alignment (power of 2) (galign >= align) + * align = register byte alignment (power of 2) + * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz) + * (not including any pad bytes required to galign this or next reg) + * dbnum = unique target number f/debug (see ) + * base = reg shortname w/o index (or sr=special, ur=TIE user reg) + * regnum = reg index in regfile, or special/TIE-user reg number + * bitsz = number of significant bits (regfile width, or ur/sr mask bits) + * gapsz = intervening bits, if bitsz bits not stored contiguously + * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize) + * reset = register reset value (or 0 if undefined at reset) + * x = reserved for future use (0 until then) + * + * To filter out certain registers, e.g. to expand only the non-global + * registers used by the compiler, you can do something like this: + * + * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p) + * #define SELCC0(p...) + * #define SELCC1(abikind,p...) SELAK##abikind(p) + * #define SELAK0(p...) REG(p) + * #define SELAK1(p...) REG(p) + * #define SELAK2(p...) + * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \ + * ...what you want to expand... + */ + +#define XCHAL_NCP_SA_NUM 0 +#define XCHAL_NCP_SA_LIST(s) /* empty */ + +#define XCHAL_CP0_SA_NUM 0 +#define XCHAL_CP0_SA_LIST(s) /* empty */ + +#define XCHAL_CP1_SA_NUM 0 +#define XCHAL_CP1_SA_LIST(s) /* empty */ + +#define XCHAL_CP2_SA_NUM 0 +#define XCHAL_CP2_SA_LIST(s) /* empty */ + +#define XCHAL_CP3_SA_NUM 0 +#define XCHAL_CP3_SA_LIST(s) /* empty */ + +#define XCHAL_CP4_SA_NUM 0 +#define XCHAL_CP4_SA_LIST(s) /* empty */ + +#define XCHAL_CP5_SA_NUM 0 +#define XCHAL_CP5_SA_LIST(s) /* empty */ + +#define XCHAL_CP6_SA_NUM 0 +#define XCHAL_CP6_SA_LIST(s) /* empty */ + +#define XCHAL_CP7_SA_NUM 0 +#define XCHAL_CP7_SA_LIST(s) /* empty */ + +/* Byte length of instruction from its first nibble (op0 field), per FLIX. */ +#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3 + +#endif /*_XTENSA_CORE_TIE_H*/ + diff --git a/extra_include/xtensa/coreasm.h b/extra_include/xtensa/coreasm.h index 591ba019..45d46853 100644 --- a/extra_include/xtensa/coreasm.h +++ b/extra_include/xtensa/coreasm.h @@ -1,914 +1,914 @@ -/* - * xtensa/coreasm.h -- assembler-specific definitions that depend on CORE configuration - * - * Source for configuration-independent binaries (which link in a - * configuration-specific HAL library) must NEVER include this file. - * It is perfectly normal, however, for the HAL itself to include this file. - * - * This file must NOT include xtensa/config/system.h. Any assembler - * header file that depends on system information should likely go - * in a new systemasm.h (or sysasm.h) header file. - * - * NOTE: macro beqi32 is NOT configuration-dependent, and is placed - * here until we have a proper configuration-independent header file. - */ - -/* $Id: //depot/rel/Boreal/Xtensa/OS/include/xtensa/coreasm.h#2 $ */ - -/* - * Copyright (c) 2000-2007 Tensilica Inc. - * - * 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 XTENSA_COREASM_H -#define XTENSA_COREASM_H - -/* - * Tell header files this is assembly source, so they can avoid non-assembler - * definitions (eg. C types etc): - */ -#ifndef _ASMLANGUAGE /* conditionalize to avoid cpp warnings (3rd parties might use same macro) */ -#define _ASMLANGUAGE -#endif - -#include -#include - -/* - * Assembly-language specific definitions (assembly macros, etc.). - */ - -/*---------------------------------------------------------------------- - * find_ms_setbit - * - * This macro finds the most significant bit that is set in - * and return its index + in , or - 1 if is zero. - * The index counts starting at zero for the lsbit, so the return - * value ranges from -1 (no bit set) to +31 (msbit set). - * - * Parameters: - * destination address register (any register) - * source address register - * temporary address register (must be different than ) - * constant value added to result (usually 0 or 1) - * On entry: - * = undefined if different than - * = value whose most significant set bit is to be found - * = undefined - * no other registers are used by this macro. - * On exit: - * = + index of msbit set in original , - * = - 1 if original was zero. - * clobbered (if not ) - * clobbered (if not ) - * Example: - * find_ms_setbit a0, a4, a0, 0 -- return in a0 index of msbit set in a4 - */ - - .macro find_ms_setbit ad, as, at, base -#if XCHAL_HAVE_NSA - movi \at, 31+\base - nsau \as, \as // get index of \as, numbered from msbit (32 if absent) - sub \ad, \at, \as // get numbering from lsbit (0..31, -1 if absent) -#else /* XCHAL_HAVE_NSA */ - movi \at, \base // start with result of 0 (point to lsbit of 32) - - beqz \as, 2f // special case for zero argument: return -1 - bltui \as, 0x10000, 1f // is it one of the 16 lsbits? (if so, check lower 16 bits) - addi \at, \at, 16 // no, increment result to upper 16 bits (of 32) - //srli \as, \as, 16 // check upper half (shift right 16 bits) - extui \as, \as, 16, 16 // check upper half (shift right 16 bits) -1: bltui \as, 0x100, 1f // is it one of the 8 lsbits? (if so, check lower 8 bits) - addi \at, \at, 8 // no, increment result to upper 8 bits (of 16) - srli \as, \as, 8 // shift right to check upper 8 bits -1: bltui \as, 0x10, 1f // is it one of the 4 lsbits? (if so, check lower 4 bits) - addi \at, \at, 4 // no, increment result to upper 4 bits (of 8) - srli \as, \as, 4 // shift right 4 bits to check upper half -1: bltui \as, 0x4, 1f // is it one of the 2 lsbits? (if so, check lower 2 bits) - addi \at, \at, 2 // no, increment result to upper 2 bits (of 4) - srli \as, \as, 2 // shift right 2 bits to check upper half -1: bltui \as, 0x2, 1f // is it the lsbit? - addi \at, \at, 2 // no, increment result to upper bit (of 2) -2: addi \at, \at, -1 // (from just above: add 1; from beqz: return -1) - //srli \as, \as, 1 -1: // done! \at contains index of msbit set (or -1 if none set) - .if 0x\ad - 0x\at // destination different than \at ? (works because regs are a0-a15) - mov \ad, \at // then move result to \ad - .endif -#endif /* XCHAL_HAVE_NSA */ - .endm // find_ms_setbit - -/*---------------------------------------------------------------------- - * find_ls_setbit - * - * This macro finds the least significant bit that is set in , - * and return its index in . - * Usage is the same as for the find_ms_setbit macro. - * Example: - * find_ls_setbit a0, a4, a0, 0 -- return in a0 index of lsbit set in a4 - */ - - .macro find_ls_setbit ad, as, at, base - neg \at, \as // keep only the least-significant bit that is set... - and \as, \at, \as // ... in \as - find_ms_setbit \ad, \as, \at, \base - .endm // find_ls_setbit - -/*---------------------------------------------------------------------- - * find_ls_one - * - * Same as find_ls_setbit with base zero. - * Source (as) and destination (ad) registers must be different. - * Provided for backward compatibility. - */ - - .macro find_ls_one ad, as - find_ls_setbit \ad, \as, \ad, 0 - .endm // find_ls_one - -/*---------------------------------------------------------------------- - * floop, floopnez, floopgtz, floopend - * - * These macros are used for fast inner loops that - * work whether or not the Loops options is configured. - * If the Loops option is configured, they simply use - * the zero-overhead LOOP instructions; otherwise - * they use explicit decrement and branch instructions. - * - * They are used in pairs, with floop, floopnez or floopgtz - * at the beginning of the loop, and floopend at the end. - * - * Each pair of loop macro calls must be given the loop count - * address register and a unique label for that loop. - * - * Example: - * - * movi a3, 16 // loop 16 times - * floop a3, myloop1 - * : - * bnez a7, end1 // exit loop if a7 != 0 - * : - * floopend a3, myloop1 - * end1: - * - * Like the LOOP instructions, these macros cannot be - * nested, must include at least one instruction, - * cannot call functions inside the loop, etc. - * The loop can be exited by jumping to the instruction - * following floopend (or elsewhere outside the loop), - * or continued by jumping to a NOP instruction placed - * immediately before floopend. - * - * Unlike LOOP instructions, the register passed to floop* - * cannot be used inside the loop, because it is used as - * the loop counter if the Loops option is not configured. - * And its value is undefined after exiting the loop. - * And because the loop counter register is active inside - * the loop, you can't easily use this construct to loop - * across a register file using ROTW as you might with LOOP - * instructions, unless you copy the loop register along. - */ - - /* Named label version of the macros: */ - - .macro floop ar, endlabel - floop_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel - .endm - - .macro floopnez ar, endlabel - floopnez_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel - .endm - - .macro floopgtz ar, endlabel - floopgtz_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel - .endm - - .macro floopend ar, endlabel - floopend_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel - .endm - - /* Numbered local label version of the macros: */ -#if 0 /*UNTESTED*/ - .macro floop89 ar - floop_ \ar, 8, 9f - .endm - - .macro floopnez89 ar - floopnez_ \ar, 8, 9f - .endm - - .macro floopgtz89 ar - floopgtz_ \ar, 8, 9f - .endm - - .macro floopend89 ar - floopend_ \ar, 8b, 9 - .endm -#endif /*0*/ - - /* Underlying version of the macros: */ - - .macro floop_ ar, startlabel, endlabelref - .ifdef _infloop_ - .if _infloop_ - .err // Error: floop cannot be nested - .endif - .endif - .set _infloop_, 1 -#if XCHAL_HAVE_LOOPS - loop \ar, \endlabelref -#else /* XCHAL_HAVE_LOOPS */ -\startlabel: - addi \ar, \ar, -1 -#endif /* XCHAL_HAVE_LOOPS */ - .endm // floop_ - - .macro floopnez_ ar, startlabel, endlabelref - .ifdef _infloop_ - .if _infloop_ - .err // Error: floopnez cannot be nested - .endif - .endif - .set _infloop_, 1 -#if XCHAL_HAVE_LOOPS - loopnez \ar, \endlabelref -#else /* XCHAL_HAVE_LOOPS */ - beqz \ar, \endlabelref -\startlabel: - addi \ar, \ar, -1 -#endif /* XCHAL_HAVE_LOOPS */ - .endm // floopnez_ - - .macro floopgtz_ ar, startlabel, endlabelref - .ifdef _infloop_ - .if _infloop_ - .err // Error: floopgtz cannot be nested - .endif - .endif - .set _infloop_, 1 -#if XCHAL_HAVE_LOOPS - loopgtz \ar, \endlabelref -#else /* XCHAL_HAVE_LOOPS */ - bltz \ar, \endlabelref - beqz \ar, \endlabelref -\startlabel: - addi \ar, \ar, -1 -#endif /* XCHAL_HAVE_LOOPS */ - .endm // floopgtz_ - - - .macro floopend_ ar, startlabelref, endlabel - .ifndef _infloop_ - .err // Error: floopend without matching floopXXX - .endif - .ifeq _infloop_ - .err // Error: floopend without matching floopXXX - .endif - .set _infloop_, 0 -#if ! XCHAL_HAVE_LOOPS - bnez \ar, \startlabelref -#endif /* XCHAL_HAVE_LOOPS */ -\endlabel: - .endm // floopend_ - -/*---------------------------------------------------------------------- - * crsil -- conditional RSIL (read/set interrupt level) - * - * Executes the RSIL instruction if it exists, else just reads PS. - * The RSIL instruction does not exist in the new exception architecture - * if the interrupt option is not selected. - */ - - .macro crsil ar, newlevel -#if XCHAL_HAVE_OLD_EXC_ARCH || XCHAL_HAVE_INTERRUPTS - rsil \ar, \newlevel -#else - rsr \ar, PS -#endif - .endm // crsil - -/*---------------------------------------------------------------------- - * safe_movi_a0 -- move constant into a0 when L32R is not safe - * - * This macro is typically used by interrupt/exception handlers. - * Loads a 32-bit constant in a0, without using any other register, - * and without corrupting the LITBASE register, even when the - * value of the LITBASE register is unknown (eg. when application - * code and interrupt/exception handling code are built independently, - * and thus with independent values of the LITBASE register; - * debug monitors are one example of this). - * - * Worst-case size of resulting code: 17 bytes. - */ - - .macro safe_movi_a0 constant -#if XCHAL_HAVE_ABSOLUTE_LITERALS - /* Contort a PC-relative literal load even though we may be in litbase-relative mode: */ - j 1f - .begin no-transform // ensure what follows is assembled exactly as-is - .align 4 // ensure constant and call0 target ... - .byte 0 // ... are 4-byte aligned (call0 instruction is 3 bytes long) -1: call0 2f // read PC (that follows call0) in a0 - .long \constant // 32-bit constant to load into a0 -2: - .end no-transform - l32i a0, a0, 0 // load constant -#else - movi a0, \constant // no LITBASE, can assume PC-relative L32R -#endif - .endm - - - - -/*---------------------------------------------------------------------- - * window_spill{4,8,12} - * - * These macros spill callers' register windows to the stack. - * They work for both privileged and non-privileged tasks. - * Must be called from a windowed ABI context, eg. within - * a windowed ABI function (ie. valid stack frame, window - * exceptions enabled, not in exception mode, etc). - * - * This macro requires a single invocation of the window_spill_common - * macro in the same assembly unit and section. - * - * Note that using window_spill{4,8,12} macros is more efficient - * than calling a function implemented using window_spill_function, - * because the latter needs extra code to figure out the size of - * the call to the spilling function. - * - * Example usage: - * - * .text - * .align 4 - * .global some_function - * .type some_function,@function - * some_function: - * entry a1, 16 - * : - * : - * - * window_spill4 // Spill windows of some_function's callers; preserves a0..a3 only; - * // to use window_spill{8,12} in this example function we'd have - * // to increase space allocated by the entry instruction, because - * // 16 bytes only allows call4; 32 or 48 bytes (+locals) are needed - * // for call8/window_spill8 or call12/window_spill12 respectively. - * - * : - * - * retw - * - * window_spill_common // instantiates code used by window_spill4 - * - * - * On entry: - * none (if window_spill4) - * stack frame has enough space allocated for call8 (if window_spill8) - * stack frame has enough space allocated for call12 (if window_spill12) - * On exit: - * a4..a15 clobbered (if window_spill4) - * a8..a15 clobbered (if window_spill8) - * a12..a15 clobbered (if window_spill12) - * no caller windows are in live registers - */ - - .macro window_spill4 -#if XCHAL_HAVE_WINDOWED -# if XCHAL_NUM_AREGS == 16 - movi a15, 0 // for 16-register files, no need to call to reach the end -# elif XCHAL_NUM_AREGS == 32 - call4 .L__wdwspill_assist28 // call deep enough to clear out any live callers -# elif XCHAL_NUM_AREGS == 64 - call4 .L__wdwspill_assist60 // call deep enough to clear out any live callers -# endif -#endif - .endm // window_spill4 - - .macro window_spill8 -#if XCHAL_HAVE_WINDOWED -# if XCHAL_NUM_AREGS == 16 - movi a15, 0 // for 16-register files, no need to call to reach the end -# elif XCHAL_NUM_AREGS == 32 - call8 .L__wdwspill_assist24 // call deep enough to clear out any live callers -# elif XCHAL_NUM_AREGS == 64 - call8 .L__wdwspill_assist56 // call deep enough to clear out any live callers -# endif -#endif - .endm // window_spill8 - - .macro window_spill12 -#if XCHAL_HAVE_WINDOWED -# if XCHAL_NUM_AREGS == 16 - movi a15, 0 // for 16-register files, no need to call to reach the end -# elif XCHAL_NUM_AREGS == 32 - call12 .L__wdwspill_assist20 // call deep enough to clear out any live callers -# elif XCHAL_NUM_AREGS == 64 - call12 .L__wdwspill_assist52 // call deep enough to clear out any live callers -# endif -#endif - .endm // window_spill12 - - -/*---------------------------------------------------------------------- - * window_spill_function - * - * This macro outputs a function that will spill its caller's callers' - * register windows to the stack. Eg. it could be used to implement - * a version of xthal_window_spill() that works in non-privileged tasks. - * This works for both privileged and non-privileged tasks. - * - * Typical usage: - * - * .text - * .align 4 - * .global my_spill_function - * .type my_spill_function,@function - * my_spill_function: - * window_spill_function - * - * On entry to resulting function: - * none - * On exit from resulting function: - * none (no caller windows are in live registers) - */ - - .macro window_spill_function -#if XCHAL_HAVE_WINDOWED -# if XCHAL_NUM_AREGS == 32 - entry sp, 48 - bbci.l a0, 31, 1f // branch if called with call4 - bbsi.l a0, 30, 2f // branch if called with call12 - call8 .L__wdwspill_assist16 // called with call8, only need another 8 - retw -1: call12 .L__wdwspill_assist16 // called with call4, only need another 12 - retw -2: call4 .L__wdwspill_assist16 // called with call12, only need another 4 - retw -# elif XCHAL_NUM_AREGS == 64 - entry sp, 48 - bbci.l a0, 31, 1f // branch if called with call4 - bbsi.l a0, 30, 2f // branch if called with call12 - call4 .L__wdwspill_assist52 // called with call8, only need a call4 - retw -1: call8 .L__wdwspill_assist52 // called with call4, only need a call8 - retw -2: call12 .L__wdwspill_assist40 // called with call12, can skip a call12 - retw -# elif XCHAL_NUM_AREGS == 16 - entry sp, 16 - bbci.l a0, 31, 1f // branch if called with call4 - bbsi.l a0, 30, 2f // branch if called with call12 - movi a7, 0 // called with call8 - retw -1: movi a11, 0 // called with call4 -2: retw // if called with call12, everything already spilled - -// movi a15, 0 // trick to spill all but the direct caller -// j 1f -// // The entry instruction is magical in the assembler (gets auto-aligned) -// // so we have to jump to it to avoid falling through the padding. -// // We need entry/retw to know where to return. -//1: entry sp, 16 -// retw -# else -# error "unrecognized address register file size" -# endif - -#endif /* XCHAL_HAVE_WINDOWED */ - window_spill_common - .endm // window_spill_function - -/*---------------------------------------------------------------------- - * window_spill_common - * - * Common code used by any number of invocations of the window_spill## - * and window_spill_function macros. - * - * Must be instantiated exactly once within a given assembly unit, - * within call/j range of and same section as window_spill## - * macro invocations for that assembly unit. - * (Is automatically instantiated by the window_spill_function macro.) - */ - - .macro window_spill_common -#if XCHAL_HAVE_WINDOWED && (XCHAL_NUM_AREGS == 32 || XCHAL_NUM_AREGS == 64) - .ifndef .L__wdwspill_defined -# if XCHAL_NUM_AREGS >= 64 -.L__wdwspill_assist60: - entry sp, 32 - call8 .L__wdwspill_assist52 - retw -.L__wdwspill_assist56: - entry sp, 16 - call4 .L__wdwspill_assist52 - retw -.L__wdwspill_assist52: - entry sp, 48 - call12 .L__wdwspill_assist40 - retw -.L__wdwspill_assist40: - entry sp, 48 - call12 .L__wdwspill_assist28 - retw -# endif -.L__wdwspill_assist28: - entry sp, 48 - call12 .L__wdwspill_assist16 - retw -.L__wdwspill_assist24: - entry sp, 32 - call8 .L__wdwspill_assist16 - retw -.L__wdwspill_assist20: - entry sp, 16 - call4 .L__wdwspill_assist16 - retw -.L__wdwspill_assist16: - entry sp, 16 - movi a15, 0 - retw - .set .L__wdwspill_defined, 1 - .endif -#endif /* XCHAL_HAVE_WINDOWED with 32 or 64 aregs */ - .endm // window_spill_common - -/*---------------------------------------------------------------------- - * beqi32 - * - * macro implements version of beqi for arbitrary 32-bit immediate value - * - * beqi32 ax, ay, imm32, label - * - * Compares value in register ax with imm32 value and jumps to label if - * equal. Clobbers register ay if needed - * - */ - .macro beqi32 ax, ay, imm, label - .ifeq ((\imm-1) & ~7) // 1..8 ? - beqi \ax, \imm, \label - .else - .ifeq (\imm+1) // -1 ? - beqi \ax, \imm, \label - .else - .ifeq (\imm) // 0 ? - beqz \ax, \label - .else - // We could also handle immediates 10,12,16,32,64,128,256 - // but it would be a long macro... - movi \ay, \imm - beq \ax, \ay, \label - .endif - .endif - .endif - .endm // beqi32 - -/*---------------------------------------------------------------------- - * isync_retw_nop - * - * This macro must be invoked immediately after ISYNC if ISYNC - * would otherwise be immediately followed by RETW (or other instruction - * modifying WindowBase or WindowStart), in a context where - * kernel vector mode may be selected, and level-one interrupts - * and window overflows may be enabled, on an XEA1 configuration. - * - * On hardware with erratum "XEA1KWIN" (see for details), - * XEA1 code must have at least one instruction between ISYNC and RETW if - * run in kernel vector mode with interrupts and window overflows enabled. - */ - .macro isync_retw_nop -#if XCHAL_MAYHAVE_ERRATUM_XEA1KWIN - nop -#endif - .endm - - - -/*---------------------------------------------------------------------- - * abs - * - * implements abs on machines that do not have it configured - */ - -#if !XCHAL_HAVE_ABS - .macro abs arr, ars - .ifc \arr, \ars - //src equal dest is less efficient - bgez \arr, 1f - neg \arr, \arr -1: - .else - neg \arr, \ars - movgez \arr, \ars, \ars - .endif - .endm -#endif /* !XCHAL_HAVE_ABS */ - - -/*---------------------------------------------------------------------- - * addx2 - * - * implements addx2 on machines that do not have it configured - * - */ - -#if !XCHAL_HAVE_ADDX - .macro addx2 arr, ars, art - .ifc \arr, \art - .ifc \arr, \ars - // addx2 a, a, a (not common) - .err - .else - add \arr, \ars, \art - add \arr, \ars, \art - .endif - .else - //addx2 a, b, c - //addx2 a, a, b - //addx2 a, b, b - slli \arr, \ars, 1 - add \arr, \arr, \art - .endif - .endm -#endif /* !XCHAL_HAVE_ADDX */ - -/*---------------------------------------------------------------------- - * addx4 - * - * implements addx4 on machines that do not have it configured - * - */ - -#if !XCHAL_HAVE_ADDX - .macro addx4 arr, ars, art - .ifc \arr, \art - .ifc \arr, \ars - // addx4 a, a, a (not common) - .err - .else - //# addx4 a, b, a - add \arr, \ars, \art - add \arr, \ars, \art - add \arr, \ars, \art - add \arr, \ars, \art - .endif - .else - //addx4 a, b, c - //addx4 a, a, b - //addx4 a, b, b - slli \arr, \ars, 2 - add \arr, \arr, \art - .endif - .endm -#endif /* !XCHAL_HAVE_ADDX */ - -/*---------------------------------------------------------------------- - * addx8 - * - * implements addx8 on machines that do not have it configured - * - */ - -#if !XCHAL_HAVE_ADDX - .macro addx8 arr, ars, art - .ifc \arr, \art - .ifc \arr, \ars - //addx8 a, a, a (not common) - .err - .else - //addx8 a, b, a - add \arr, \ars, \art - add \arr, \ars, \art - add \arr, \ars, \art - add \arr, \ars, \art - add \arr, \ars, \art - add \arr, \ars, \art - add \arr, \ars, \art - add \arr, \ars, \art - .endif - .else - //addx8 a, b, c - //addx8 a, a, b - //addx8 a, b, b - slli \arr, \ars, 3 - add \arr, \arr, \art - .endif - .endm -#endif /* !XCHAL_HAVE_ADDX */ - - -/*---------------------------------------------------------------------- - * rfe_rfue - * - * Maps to RFUE on XEA1, and RFE on XEA2. No mapping on XEAX. - */ - -#if XCHAL_HAVE_XEA1 - .macro rfe_rfue - rfue - .endm -#elif XCHAL_HAVE_XEA2 - .macro rfe_rfue - rfe - .endm -#endif - - -/*---------------------------------------------------------------------- - * abi_entry - * - * Generate proper function entry sequence for the current ABI - * (windowed or call0). Takes care of allocating stack space (up to 1kB) - * and saving the return PC, if necessary. The corresponding abi_return - * macro does the corresponding stack deallocation and restoring return PC. - * - * Parameters are: - * - * locsize Number of bytes to allocate on the stack - * for local variables (and for args to pass to - * callees, if any calls are made). Defaults to zero. - * The macro rounds this up to a multiple of 16. - * NOTE: large values are allowed (e.g. up to 1 GB). - * - * callsize Maximum call size made by this function. - * Leave zero (default) for leaf functions, i.e. if - * this function makes no calls to other functions. - * Otherwise must be set to 4, 8, or 12 according - * to whether the "largest" call made is a call[x]4, - * call[x]8, or call[x]12 (for call0 ABI, it makes - * no difference whether this is set to 4, 8 or 12, - * but it must be set to one of these values). - * - * NOTE: It is up to the caller to align the entry point, declare the - * function symbol, make it global, etc. - * - * NOTE: This macro relies on assembler relaxation for large values - * of locsize. It might not work with the no-transform directive. - * NOTE: For the call0 ABI, this macro ensures SP is allocated or - * de-allocated cleanly, i.e. without temporarily allocating too much - * (or allocating negatively!) due to addi relaxation. - * - * NOTE: Generating the proper sequence and register allocation for - * making calls in an ABI independent manner is a separate topic not - * covered by this macro. - * - * NOTE: To access arguments, you can't use a fixed offset from SP. - * The offset depends on the ABI, whether the function is leaf, etc. - * The simplest method is probably to use the .locsz symbol, which - * is set by this macro to the actual number of bytes allocated on - * the stack, in other words, to the offset from SP to the arguments. - * E.g. for a function whose arguments are all 32-bit integers, you - * can get the 7th and 8th arguments (1st and 2nd args stored on stack) - * using: - * l32i a2, sp, .locsz - * l32i a3, sp, .locsz+4 - * (this example works as long as locsize is under L32I's offset limit - * of 1020 minus up to 48 bytes of ABI-specific stack usage; - * otherwise you might first need to do "addi a?, sp, .locsz" - * or similar sequence). - * - * NOTE: For call0 ABI, this macro (and abi_return) may clobber a9 - * (a caller-saved register). - * - * Examples: - * abi_entry - * abi_entry 5 - * abi_entry 22, 8 - * abi_entry 0, 4 - */ - - /* - * Compute .locsz and .callsz without emitting any instructions. - * Used by both abi_entry and abi_return. - * Assumes locsize >= 0. - */ - .macro abi_entry_size locsize=0, callsize=0 -#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__ - .ifeq \callsize - .set .callsz, 16 - .else - .ifeq \callsize-4 - .set .callsz, 16 - .else - .ifeq \callsize-8 - .set .callsz, 32 - .else - .ifeq \callsize-12 - .set .callsz, 48 - .else - .error "abi_entry: invalid call size \callsize" - .endif - .endif - .endif - .endif - .set .locsz, .callsz + ((\locsize + 15) & -16) -#else - .set .callsz, \callsize - .if .callsz /* if calls, need space for return PC */ - .set .locsz, (\locsize + 4 + 15) & -16 - .else - .set .locsz, (\locsize + 15) & -16 - .endif -#endif - .endm - - .macro abi_entry locsize=0, callsize=0 - .iflt \locsize - .error "abi_entry: invalid negative size of locals (\locsize)" - .endif - abi_entry_size \locsize, \callsize -#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__ - .ifgt .locsz - 32760 /* .locsz > 32760 (ENTRY's max range)? */ - /* Funky computation to try to have assembler use addmi efficiently if possible: */ - entry sp, 0x7F00 + (.locsz & 0xF0) - addi a12, sp, - ((.locsz & -0x100) - 0x7F00) - movsp sp, a12 - .else - entry sp, .locsz - .endif -#else - .if .locsz - .ifle .locsz - 128 /* if locsz <= 128 */ - addi sp, sp, -.locsz - .if .callsz - s32i a0, sp, .locsz - 4 - .endif - .elseif .callsz /* locsz > 128, with calls: */ - movi a9, .locsz - 16 /* note: a9 is caller-saved */ - addi sp, sp, -16 - s32i a0, sp, 12 - sub sp, sp, a9 - .else /* locsz > 128, no calls: */ - movi a9, .locsz - sub sp, sp, a9 - .endif /* end */ - .endif -#endif - .endm - - - -/*---------------------------------------------------------------------- - * abi_return - * - * Generate proper function exit sequence for the current ABI - * (windowed or call0). Takes care of freeing stack space and - * restoring the return PC, if necessary. - * NOTE: This macro MUST be invoked following a corresponding - * abi_entry macro invocation. For call0 ABI in particular, - * all stack and PC restoration are done according to the last - * abi_entry macro invoked before this macro in the assembly file. - * - * Normally this macro takes no arguments. However to allow - * for placing abi_return *before* abi_entry (as must be done - * for some highly optimized assembly), it optionally takes - * exactly the same arguments as abi_entry. - */ - - .macro abi_return locsize=-1, callsize=0 - .ifge \locsize - abi_entry_size \locsize, \callsize - .endif -#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__ - retw -#else - .if .locsz - .iflt .locsz - 128 /* if locsz < 128 */ - .if .callsz - l32i a0, sp, .locsz - 4 - .endif - addi sp, sp, .locsz - .elseif .callsz /* locsz >= 128, with calls: */ - addi a9, sp, .locsz - 16 - l32i a0, a9, 12 - addi sp, a9, 16 - .else /* locsz >= 128, no calls: */ - movi a9, .locsz - add sp, sp, a9 - .endif /* end */ - .endif - ret -#endif - .endm - - -#endif /*XTENSA_COREASM_H*/ - +/* + * xtensa/coreasm.h -- assembler-specific definitions that depend on CORE configuration + * + * Source for configuration-independent binaries (which link in a + * configuration-specific HAL library) must NEVER include this file. + * It is perfectly normal, however, for the HAL itself to include this file. + * + * This file must NOT include xtensa/config/system.h. Any assembler + * header file that depends on system information should likely go + * in a new systemasm.h (or sysasm.h) header file. + * + * NOTE: macro beqi32 is NOT configuration-dependent, and is placed + * here until we have a proper configuration-independent header file. + */ + +/* $Id: //depot/rel/Boreal/Xtensa/OS/include/xtensa/coreasm.h#2 $ */ + +/* + * Copyright (c) 2000-2007 Tensilica Inc. + * + * 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 XTENSA_COREASM_H +#define XTENSA_COREASM_H + +/* + * Tell header files this is assembly source, so they can avoid non-assembler + * definitions (eg. C types etc): + */ +#ifndef _ASMLANGUAGE /* conditionalize to avoid cpp warnings (3rd parties might use same macro) */ +#define _ASMLANGUAGE +#endif + +#include +#include + +/* + * Assembly-language specific definitions (assembly macros, etc.). + */ + +/*---------------------------------------------------------------------- + * find_ms_setbit + * + * This macro finds the most significant bit that is set in + * and return its index + in , or - 1 if is zero. + * The index counts starting at zero for the lsbit, so the return + * value ranges from -1 (no bit set) to +31 (msbit set). + * + * Parameters: + * destination address register (any register) + * source address register + * temporary address register (must be different than ) + * constant value added to result (usually 0 or 1) + * On entry: + * = undefined if different than + * = value whose most significant set bit is to be found + * = undefined + * no other registers are used by this macro. + * On exit: + * = + index of msbit set in original , + * = - 1 if original was zero. + * clobbered (if not ) + * clobbered (if not ) + * Example: + * find_ms_setbit a0, a4, a0, 0 -- return in a0 index of msbit set in a4 + */ + + .macro find_ms_setbit ad, as, at, base +#if XCHAL_HAVE_NSA + movi \at, 31+\base + nsau \as, \as // get index of \as, numbered from msbit (32 if absent) + sub \ad, \at, \as // get numbering from lsbit (0..31, -1 if absent) +#else /* XCHAL_HAVE_NSA */ + movi \at, \base // start with result of 0 (point to lsbit of 32) + + beqz \as, 2f // special case for zero argument: return -1 + bltui \as, 0x10000, 1f // is it one of the 16 lsbits? (if so, check lower 16 bits) + addi \at, \at, 16 // no, increment result to upper 16 bits (of 32) + //srli \as, \as, 16 // check upper half (shift right 16 bits) + extui \as, \as, 16, 16 // check upper half (shift right 16 bits) +1: bltui \as, 0x100, 1f // is it one of the 8 lsbits? (if so, check lower 8 bits) + addi \at, \at, 8 // no, increment result to upper 8 bits (of 16) + srli \as, \as, 8 // shift right to check upper 8 bits +1: bltui \as, 0x10, 1f // is it one of the 4 lsbits? (if so, check lower 4 bits) + addi \at, \at, 4 // no, increment result to upper 4 bits (of 8) + srli \as, \as, 4 // shift right 4 bits to check upper half +1: bltui \as, 0x4, 1f // is it one of the 2 lsbits? (if so, check lower 2 bits) + addi \at, \at, 2 // no, increment result to upper 2 bits (of 4) + srli \as, \as, 2 // shift right 2 bits to check upper half +1: bltui \as, 0x2, 1f // is it the lsbit? + addi \at, \at, 2 // no, increment result to upper bit (of 2) +2: addi \at, \at, -1 // (from just above: add 1; from beqz: return -1) + //srli \as, \as, 1 +1: // done! \at contains index of msbit set (or -1 if none set) + .if 0x\ad - 0x\at // destination different than \at ? (works because regs are a0-a15) + mov \ad, \at // then move result to \ad + .endif +#endif /* XCHAL_HAVE_NSA */ + .endm // find_ms_setbit + +/*---------------------------------------------------------------------- + * find_ls_setbit + * + * This macro finds the least significant bit that is set in , + * and return its index in . + * Usage is the same as for the find_ms_setbit macro. + * Example: + * find_ls_setbit a0, a4, a0, 0 -- return in a0 index of lsbit set in a4 + */ + + .macro find_ls_setbit ad, as, at, base + neg \at, \as // keep only the least-significant bit that is set... + and \as, \at, \as // ... in \as + find_ms_setbit \ad, \as, \at, \base + .endm // find_ls_setbit + +/*---------------------------------------------------------------------- + * find_ls_one + * + * Same as find_ls_setbit with base zero. + * Source (as) and destination (ad) registers must be different. + * Provided for backward compatibility. + */ + + .macro find_ls_one ad, as + find_ls_setbit \ad, \as, \ad, 0 + .endm // find_ls_one + +/*---------------------------------------------------------------------- + * floop, floopnez, floopgtz, floopend + * + * These macros are used for fast inner loops that + * work whether or not the Loops options is configured. + * If the Loops option is configured, they simply use + * the zero-overhead LOOP instructions; otherwise + * they use explicit decrement and branch instructions. + * + * They are used in pairs, with floop, floopnez or floopgtz + * at the beginning of the loop, and floopend at the end. + * + * Each pair of loop macro calls must be given the loop count + * address register and a unique label for that loop. + * + * Example: + * + * movi a3, 16 // loop 16 times + * floop a3, myloop1 + * : + * bnez a7, end1 // exit loop if a7 != 0 + * : + * floopend a3, myloop1 + * end1: + * + * Like the LOOP instructions, these macros cannot be + * nested, must include at least one instruction, + * cannot call functions inside the loop, etc. + * The loop can be exited by jumping to the instruction + * following floopend (or elsewhere outside the loop), + * or continued by jumping to a NOP instruction placed + * immediately before floopend. + * + * Unlike LOOP instructions, the register passed to floop* + * cannot be used inside the loop, because it is used as + * the loop counter if the Loops option is not configured. + * And its value is undefined after exiting the loop. + * And because the loop counter register is active inside + * the loop, you can't easily use this construct to loop + * across a register file using ROTW as you might with LOOP + * instructions, unless you copy the loop register along. + */ + + /* Named label version of the macros: */ + + .macro floop ar, endlabel + floop_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel + .endm + + .macro floopnez ar, endlabel + floopnez_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel + .endm + + .macro floopgtz ar, endlabel + floopgtz_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel + .endm + + .macro floopend ar, endlabel + floopend_ \ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel + .endm + + /* Numbered local label version of the macros: */ +#if 0 /*UNTESTED*/ + .macro floop89 ar + floop_ \ar, 8, 9f + .endm + + .macro floopnez89 ar + floopnez_ \ar, 8, 9f + .endm + + .macro floopgtz89 ar + floopgtz_ \ar, 8, 9f + .endm + + .macro floopend89 ar + floopend_ \ar, 8b, 9 + .endm +#endif /*0*/ + + /* Underlying version of the macros: */ + + .macro floop_ ar, startlabel, endlabelref + .ifdef _infloop_ + .if _infloop_ + .err // Error: floop cannot be nested + .endif + .endif + .set _infloop_, 1 +#if XCHAL_HAVE_LOOPS + loop \ar, \endlabelref +#else /* XCHAL_HAVE_LOOPS */ +\startlabel: + addi \ar, \ar, -1 +#endif /* XCHAL_HAVE_LOOPS */ + .endm // floop_ + + .macro floopnez_ ar, startlabel, endlabelref + .ifdef _infloop_ + .if _infloop_ + .err // Error: floopnez cannot be nested + .endif + .endif + .set _infloop_, 1 +#if XCHAL_HAVE_LOOPS + loopnez \ar, \endlabelref +#else /* XCHAL_HAVE_LOOPS */ + beqz \ar, \endlabelref +\startlabel: + addi \ar, \ar, -1 +#endif /* XCHAL_HAVE_LOOPS */ + .endm // floopnez_ + + .macro floopgtz_ ar, startlabel, endlabelref + .ifdef _infloop_ + .if _infloop_ + .err // Error: floopgtz cannot be nested + .endif + .endif + .set _infloop_, 1 +#if XCHAL_HAVE_LOOPS + loopgtz \ar, \endlabelref +#else /* XCHAL_HAVE_LOOPS */ + bltz \ar, \endlabelref + beqz \ar, \endlabelref +\startlabel: + addi \ar, \ar, -1 +#endif /* XCHAL_HAVE_LOOPS */ + .endm // floopgtz_ + + + .macro floopend_ ar, startlabelref, endlabel + .ifndef _infloop_ + .err // Error: floopend without matching floopXXX + .endif + .ifeq _infloop_ + .err // Error: floopend without matching floopXXX + .endif + .set _infloop_, 0 +#if ! XCHAL_HAVE_LOOPS + bnez \ar, \startlabelref +#endif /* XCHAL_HAVE_LOOPS */ +\endlabel: + .endm // floopend_ + +/*---------------------------------------------------------------------- + * crsil -- conditional RSIL (read/set interrupt level) + * + * Executes the RSIL instruction if it exists, else just reads PS. + * The RSIL instruction does not exist in the new exception architecture + * if the interrupt option is not selected. + */ + + .macro crsil ar, newlevel +#if XCHAL_HAVE_OLD_EXC_ARCH || XCHAL_HAVE_INTERRUPTS + rsil \ar, \newlevel +#else + rsr \ar, PS +#endif + .endm // crsil + +/*---------------------------------------------------------------------- + * safe_movi_a0 -- move constant into a0 when L32R is not safe + * + * This macro is typically used by interrupt/exception handlers. + * Loads a 32-bit constant in a0, without using any other register, + * and without corrupting the LITBASE register, even when the + * value of the LITBASE register is unknown (eg. when application + * code and interrupt/exception handling code are built independently, + * and thus with independent values of the LITBASE register; + * debug monitors are one example of this). + * + * Worst-case size of resulting code: 17 bytes. + */ + + .macro safe_movi_a0 constant +#if XCHAL_HAVE_ABSOLUTE_LITERALS + /* Contort a PC-relative literal load even though we may be in litbase-relative mode: */ + j 1f + .begin no-transform // ensure what follows is assembled exactly as-is + .align 4 // ensure constant and call0 target ... + .byte 0 // ... are 4-byte aligned (call0 instruction is 3 bytes long) +1: call0 2f // read PC (that follows call0) in a0 + .long \constant // 32-bit constant to load into a0 +2: + .end no-transform + l32i a0, a0, 0 // load constant +#else + movi a0, \constant // no LITBASE, can assume PC-relative L32R +#endif + .endm + + + + +/*---------------------------------------------------------------------- + * window_spill{4,8,12} + * + * These macros spill callers' register windows to the stack. + * They work for both privileged and non-privileged tasks. + * Must be called from a windowed ABI context, eg. within + * a windowed ABI function (ie. valid stack frame, window + * exceptions enabled, not in exception mode, etc). + * + * This macro requires a single invocation of the window_spill_common + * macro in the same assembly unit and section. + * + * Note that using window_spill{4,8,12} macros is more efficient + * than calling a function implemented using window_spill_function, + * because the latter needs extra code to figure out the size of + * the call to the spilling function. + * + * Example usage: + * + * .text + * .align 4 + * .global some_function + * .type some_function,@function + * some_function: + * entry a1, 16 + * : + * : + * + * window_spill4 // Spill windows of some_function's callers; preserves a0..a3 only; + * // to use window_spill{8,12} in this example function we'd have + * // to increase space allocated by the entry instruction, because + * // 16 bytes only allows call4; 32 or 48 bytes (+locals) are needed + * // for call8/window_spill8 or call12/window_spill12 respectively. + * + * : + * + * retw + * + * window_spill_common // instantiates code used by window_spill4 + * + * + * On entry: + * none (if window_spill4) + * stack frame has enough space allocated for call8 (if window_spill8) + * stack frame has enough space allocated for call12 (if window_spill12) + * On exit: + * a4..a15 clobbered (if window_spill4) + * a8..a15 clobbered (if window_spill8) + * a12..a15 clobbered (if window_spill12) + * no caller windows are in live registers + */ + + .macro window_spill4 +#if XCHAL_HAVE_WINDOWED +# if XCHAL_NUM_AREGS == 16 + movi a15, 0 // for 16-register files, no need to call to reach the end +# elif XCHAL_NUM_AREGS == 32 + call4 .L__wdwspill_assist28 // call deep enough to clear out any live callers +# elif XCHAL_NUM_AREGS == 64 + call4 .L__wdwspill_assist60 // call deep enough to clear out any live callers +# endif +#endif + .endm // window_spill4 + + .macro window_spill8 +#if XCHAL_HAVE_WINDOWED +# if XCHAL_NUM_AREGS == 16 + movi a15, 0 // for 16-register files, no need to call to reach the end +# elif XCHAL_NUM_AREGS == 32 + call8 .L__wdwspill_assist24 // call deep enough to clear out any live callers +# elif XCHAL_NUM_AREGS == 64 + call8 .L__wdwspill_assist56 // call deep enough to clear out any live callers +# endif +#endif + .endm // window_spill8 + + .macro window_spill12 +#if XCHAL_HAVE_WINDOWED +# if XCHAL_NUM_AREGS == 16 + movi a15, 0 // for 16-register files, no need to call to reach the end +# elif XCHAL_NUM_AREGS == 32 + call12 .L__wdwspill_assist20 // call deep enough to clear out any live callers +# elif XCHAL_NUM_AREGS == 64 + call12 .L__wdwspill_assist52 // call deep enough to clear out any live callers +# endif +#endif + .endm // window_spill12 + + +/*---------------------------------------------------------------------- + * window_spill_function + * + * This macro outputs a function that will spill its caller's callers' + * register windows to the stack. Eg. it could be used to implement + * a version of xthal_window_spill() that works in non-privileged tasks. + * This works for both privileged and non-privileged tasks. + * + * Typical usage: + * + * .text + * .align 4 + * .global my_spill_function + * .type my_spill_function,@function + * my_spill_function: + * window_spill_function + * + * On entry to resulting function: + * none + * On exit from resulting function: + * none (no caller windows are in live registers) + */ + + .macro window_spill_function +#if XCHAL_HAVE_WINDOWED +# if XCHAL_NUM_AREGS == 32 + entry sp, 48 + bbci.l a0, 31, 1f // branch if called with call4 + bbsi.l a0, 30, 2f // branch if called with call12 + call8 .L__wdwspill_assist16 // called with call8, only need another 8 + retw +1: call12 .L__wdwspill_assist16 // called with call4, only need another 12 + retw +2: call4 .L__wdwspill_assist16 // called with call12, only need another 4 + retw +# elif XCHAL_NUM_AREGS == 64 + entry sp, 48 + bbci.l a0, 31, 1f // branch if called with call4 + bbsi.l a0, 30, 2f // branch if called with call12 + call4 .L__wdwspill_assist52 // called with call8, only need a call4 + retw +1: call8 .L__wdwspill_assist52 // called with call4, only need a call8 + retw +2: call12 .L__wdwspill_assist40 // called with call12, can skip a call12 + retw +# elif XCHAL_NUM_AREGS == 16 + entry sp, 16 + bbci.l a0, 31, 1f // branch if called with call4 + bbsi.l a0, 30, 2f // branch if called with call12 + movi a7, 0 // called with call8 + retw +1: movi a11, 0 // called with call4 +2: retw // if called with call12, everything already spilled + +// movi a15, 0 // trick to spill all but the direct caller +// j 1f +// // The entry instruction is magical in the assembler (gets auto-aligned) +// // so we have to jump to it to avoid falling through the padding. +// // We need entry/retw to know where to return. +//1: entry sp, 16 +// retw +# else +# error "unrecognized address register file size" +# endif + +#endif /* XCHAL_HAVE_WINDOWED */ + window_spill_common + .endm // window_spill_function + +/*---------------------------------------------------------------------- + * window_spill_common + * + * Common code used by any number of invocations of the window_spill## + * and window_spill_function macros. + * + * Must be instantiated exactly once within a given assembly unit, + * within call/j range of and same section as window_spill## + * macro invocations for that assembly unit. + * (Is automatically instantiated by the window_spill_function macro.) + */ + + .macro window_spill_common +#if XCHAL_HAVE_WINDOWED && (XCHAL_NUM_AREGS == 32 || XCHAL_NUM_AREGS == 64) + .ifndef .L__wdwspill_defined +# if XCHAL_NUM_AREGS >= 64 +.L__wdwspill_assist60: + entry sp, 32 + call8 .L__wdwspill_assist52 + retw +.L__wdwspill_assist56: + entry sp, 16 + call4 .L__wdwspill_assist52 + retw +.L__wdwspill_assist52: + entry sp, 48 + call12 .L__wdwspill_assist40 + retw +.L__wdwspill_assist40: + entry sp, 48 + call12 .L__wdwspill_assist28 + retw +# endif +.L__wdwspill_assist28: + entry sp, 48 + call12 .L__wdwspill_assist16 + retw +.L__wdwspill_assist24: + entry sp, 32 + call8 .L__wdwspill_assist16 + retw +.L__wdwspill_assist20: + entry sp, 16 + call4 .L__wdwspill_assist16 + retw +.L__wdwspill_assist16: + entry sp, 16 + movi a15, 0 + retw + .set .L__wdwspill_defined, 1 + .endif +#endif /* XCHAL_HAVE_WINDOWED with 32 or 64 aregs */ + .endm // window_spill_common + +/*---------------------------------------------------------------------- + * beqi32 + * + * macro implements version of beqi for arbitrary 32-bit immediate value + * + * beqi32 ax, ay, imm32, label + * + * Compares value in register ax with imm32 value and jumps to label if + * equal. Clobbers register ay if needed + * + */ + .macro beqi32 ax, ay, imm, label + .ifeq ((\imm-1) & ~7) // 1..8 ? + beqi \ax, \imm, \label + .else + .ifeq (\imm+1) // -1 ? + beqi \ax, \imm, \label + .else + .ifeq (\imm) // 0 ? + beqz \ax, \label + .else + // We could also handle immediates 10,12,16,32,64,128,256 + // but it would be a long macro... + movi \ay, \imm + beq \ax, \ay, \label + .endif + .endif + .endif + .endm // beqi32 + +/*---------------------------------------------------------------------- + * isync_retw_nop + * + * This macro must be invoked immediately after ISYNC if ISYNC + * would otherwise be immediately followed by RETW (or other instruction + * modifying WindowBase or WindowStart), in a context where + * kernel vector mode may be selected, and level-one interrupts + * and window overflows may be enabled, on an XEA1 configuration. + * + * On hardware with erratum "XEA1KWIN" (see for details), + * XEA1 code must have at least one instruction between ISYNC and RETW if + * run in kernel vector mode with interrupts and window overflows enabled. + */ + .macro isync_retw_nop +#if XCHAL_MAYHAVE_ERRATUM_XEA1KWIN + nop +#endif + .endm + + + +/*---------------------------------------------------------------------- + * abs + * + * implements abs on machines that do not have it configured + */ + +#if !XCHAL_HAVE_ABS + .macro abs arr, ars + .ifc \arr, \ars + //src equal dest is less efficient + bgez \arr, 1f + neg \arr, \arr +1: + .else + neg \arr, \ars + movgez \arr, \ars, \ars + .endif + .endm +#endif /* !XCHAL_HAVE_ABS */ + + +/*---------------------------------------------------------------------- + * addx2 + * + * implements addx2 on machines that do not have it configured + * + */ + +#if !XCHAL_HAVE_ADDX + .macro addx2 arr, ars, art + .ifc \arr, \art + .ifc \arr, \ars + // addx2 a, a, a (not common) + .err + .else + add \arr, \ars, \art + add \arr, \ars, \art + .endif + .else + //addx2 a, b, c + //addx2 a, a, b + //addx2 a, b, b + slli \arr, \ars, 1 + add \arr, \arr, \art + .endif + .endm +#endif /* !XCHAL_HAVE_ADDX */ + +/*---------------------------------------------------------------------- + * addx4 + * + * implements addx4 on machines that do not have it configured + * + */ + +#if !XCHAL_HAVE_ADDX + .macro addx4 arr, ars, art + .ifc \arr, \art + .ifc \arr, \ars + // addx4 a, a, a (not common) + .err + .else + //# addx4 a, b, a + add \arr, \ars, \art + add \arr, \ars, \art + add \arr, \ars, \art + add \arr, \ars, \art + .endif + .else + //addx4 a, b, c + //addx4 a, a, b + //addx4 a, b, b + slli \arr, \ars, 2 + add \arr, \arr, \art + .endif + .endm +#endif /* !XCHAL_HAVE_ADDX */ + +/*---------------------------------------------------------------------- + * addx8 + * + * implements addx8 on machines that do not have it configured + * + */ + +#if !XCHAL_HAVE_ADDX + .macro addx8 arr, ars, art + .ifc \arr, \art + .ifc \arr, \ars + //addx8 a, a, a (not common) + .err + .else + //addx8 a, b, a + add \arr, \ars, \art + add \arr, \ars, \art + add \arr, \ars, \art + add \arr, \ars, \art + add \arr, \ars, \art + add \arr, \ars, \art + add \arr, \ars, \art + add \arr, \ars, \art + .endif + .else + //addx8 a, b, c + //addx8 a, a, b + //addx8 a, b, b + slli \arr, \ars, 3 + add \arr, \arr, \art + .endif + .endm +#endif /* !XCHAL_HAVE_ADDX */ + + +/*---------------------------------------------------------------------- + * rfe_rfue + * + * Maps to RFUE on XEA1, and RFE on XEA2. No mapping on XEAX. + */ + +#if XCHAL_HAVE_XEA1 + .macro rfe_rfue + rfue + .endm +#elif XCHAL_HAVE_XEA2 + .macro rfe_rfue + rfe + .endm +#endif + + +/*---------------------------------------------------------------------- + * abi_entry + * + * Generate proper function entry sequence for the current ABI + * (windowed or call0). Takes care of allocating stack space (up to 1kB) + * and saving the return PC, if necessary. The corresponding abi_return + * macro does the corresponding stack deallocation and restoring return PC. + * + * Parameters are: + * + * locsize Number of bytes to allocate on the stack + * for local variables (and for args to pass to + * callees, if any calls are made). Defaults to zero. + * The macro rounds this up to a multiple of 16. + * NOTE: large values are allowed (e.g. up to 1 GB). + * + * callsize Maximum call size made by this function. + * Leave zero (default) for leaf functions, i.e. if + * this function makes no calls to other functions. + * Otherwise must be set to 4, 8, or 12 according + * to whether the "largest" call made is a call[x]4, + * call[x]8, or call[x]12 (for call0 ABI, it makes + * no difference whether this is set to 4, 8 or 12, + * but it must be set to one of these values). + * + * NOTE: It is up to the caller to align the entry point, declare the + * function symbol, make it global, etc. + * + * NOTE: This macro relies on assembler relaxation for large values + * of locsize. It might not work with the no-transform directive. + * NOTE: For the call0 ABI, this macro ensures SP is allocated or + * de-allocated cleanly, i.e. without temporarily allocating too much + * (or allocating negatively!) due to addi relaxation. + * + * NOTE: Generating the proper sequence and register allocation for + * making calls in an ABI independent manner is a separate topic not + * covered by this macro. + * + * NOTE: To access arguments, you can't use a fixed offset from SP. + * The offset depends on the ABI, whether the function is leaf, etc. + * The simplest method is probably to use the .locsz symbol, which + * is set by this macro to the actual number of bytes allocated on + * the stack, in other words, to the offset from SP to the arguments. + * E.g. for a function whose arguments are all 32-bit integers, you + * can get the 7th and 8th arguments (1st and 2nd args stored on stack) + * using: + * l32i a2, sp, .locsz + * l32i a3, sp, .locsz+4 + * (this example works as long as locsize is under L32I's offset limit + * of 1020 minus up to 48 bytes of ABI-specific stack usage; + * otherwise you might first need to do "addi a?, sp, .locsz" + * or similar sequence). + * + * NOTE: For call0 ABI, this macro (and abi_return) may clobber a9 + * (a caller-saved register). + * + * Examples: + * abi_entry + * abi_entry 5 + * abi_entry 22, 8 + * abi_entry 0, 4 + */ + + /* + * Compute .locsz and .callsz without emitting any instructions. + * Used by both abi_entry and abi_return. + * Assumes locsize >= 0. + */ + .macro abi_entry_size locsize=0, callsize=0 +#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__ + .ifeq \callsize + .set .callsz, 16 + .else + .ifeq \callsize-4 + .set .callsz, 16 + .else + .ifeq \callsize-8 + .set .callsz, 32 + .else + .ifeq \callsize-12 + .set .callsz, 48 + .else + .error "abi_entry: invalid call size \callsize" + .endif + .endif + .endif + .endif + .set .locsz, .callsz + ((\locsize + 15) & -16) +#else + .set .callsz, \callsize + .if .callsz /* if calls, need space for return PC */ + .set .locsz, (\locsize + 4 + 15) & -16 + .else + .set .locsz, (\locsize + 15) & -16 + .endif +#endif + .endm + + .macro abi_entry locsize=0, callsize=0 + .iflt \locsize + .error "abi_entry: invalid negative size of locals (\locsize)" + .endif + abi_entry_size \locsize, \callsize +#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__ + .ifgt .locsz - 32760 /* .locsz > 32760 (ENTRY's max range)? */ + /* Funky computation to try to have assembler use addmi efficiently if possible: */ + entry sp, 0x7F00 + (.locsz & 0xF0) + addi a12, sp, - ((.locsz & -0x100) - 0x7F00) + movsp sp, a12 + .else + entry sp, .locsz + .endif +#else + .if .locsz + .ifle .locsz - 128 /* if locsz <= 128 */ + addi sp, sp, -.locsz + .if .callsz + s32i a0, sp, .locsz - 4 + .endif + .elseif .callsz /* locsz > 128, with calls: */ + movi a9, .locsz - 16 /* note: a9 is caller-saved */ + addi sp, sp, -16 + s32i a0, sp, 12 + sub sp, sp, a9 + .else /* locsz > 128, no calls: */ + movi a9, .locsz + sub sp, sp, a9 + .endif /* end */ + .endif +#endif + .endm + + + +/*---------------------------------------------------------------------- + * abi_return + * + * Generate proper function exit sequence for the current ABI + * (windowed or call0). Takes care of freeing stack space and + * restoring the return PC, if necessary. + * NOTE: This macro MUST be invoked following a corresponding + * abi_entry macro invocation. For call0 ABI in particular, + * all stack and PC restoration are done according to the last + * abi_entry macro invoked before this macro in the assembly file. + * + * Normally this macro takes no arguments. However to allow + * for placing abi_return *before* abi_entry (as must be done + * for some highly optimized assembly), it optionally takes + * exactly the same arguments as abi_entry. + */ + + .macro abi_return locsize=-1, callsize=0 + .ifge \locsize + abi_entry_size \locsize, \callsize + .endif +#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__ + retw +#else + .if .locsz + .iflt .locsz - 128 /* if locsz < 128 */ + .if .callsz + l32i a0, sp, .locsz - 4 + .endif + addi sp, sp, .locsz + .elseif .callsz /* locsz >= 128, with calls: */ + addi a9, sp, .locsz - 16 + l32i a0, a9, 12 + addi sp, a9, 16 + .else /* locsz >= 128, no calls: */ + movi a9, .locsz + add sp, sp, a9 + .endif /* end */ + .endif + ret +#endif + .endm + + +#endif /*XTENSA_COREASM_H*/ + diff --git a/extra_include/xtensa/corebits.h b/extra_include/xtensa/corebits.h index 9f5154c4..762bc609 100644 --- a/extra_include/xtensa/corebits.h +++ b/extra_include/xtensa/corebits.h @@ -1,164 +1,164 @@ -/* - * xtensa/corebits.h - Xtensa Special Register field positions, masks, values. - * - * (In previous releases, these were defined in specreg.h, a generated file. - * This file is not generated, ie. it is processor configuration independent.) - */ - -/* $Id: //depot/rel/Boreal/Xtensa/OS/include/xtensa/corebits.h#2 $ */ - -/* - * Copyright (c) 2005-2007 Tensilica Inc. - * - * 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 XTENSA_COREBITS_H -#define XTENSA_COREBITS_H - -/* EXCCAUSE register fields: */ -#define EXCCAUSE_EXCCAUSE_SHIFT 0 -#define EXCCAUSE_EXCCAUSE_MASK 0x3F -/* EXCCAUSE register values: */ -/* - * General Exception Causes - * (values of EXCCAUSE special register set by general exceptions, - * which vector to the user, kernel, or double-exception vectors). - */ -#define EXCCAUSE_ILLEGAL 0 /* Illegal Instruction */ -#define EXCCAUSE_SYSCALL 1 /* System Call (SYSCALL instruction) */ -#define EXCCAUSE_INSTR_ERROR 2 /* Instruction Fetch Error */ -# define EXCCAUSE_IFETCHERROR 2 /* (backward compatibility macro, deprecated, avoid) */ -#define EXCCAUSE_LOAD_STORE_ERROR 3 /* Load Store Error */ -# define EXCCAUSE_LOADSTOREERROR 3 /* (backward compatibility macro, deprecated, avoid) */ -#define EXCCAUSE_LEVEL1_INTERRUPT 4 /* Level 1 Interrupt */ -# define EXCCAUSE_LEVEL1INTERRUPT 4 /* (backward compatibility macro, deprecated, avoid) */ -#define EXCCAUSE_ALLOCA 5 /* Stack Extension Assist (MOVSP instruction) for alloca */ -#define EXCCAUSE_DIVIDE_BY_ZERO 6 /* Integer Divide by Zero */ -#define EXCCAUSE_SPECULATION 7 /* Use of Failed Speculative Access (not implemented) */ -#define EXCCAUSE_PRIVILEGED 8 /* Privileged Instruction */ -#define EXCCAUSE_UNALIGNED 9 /* Unaligned Load or Store */ -/* Reserved 10..11 */ -#define EXCCAUSE_INSTR_DATA_ERROR 12 /* PIF Data Error on Instruction Fetch (RB-200x and later) */ -#define EXCCAUSE_LOAD_STORE_DATA_ERROR 13 /* PIF Data Error on Load or Store (RB-200x and later) */ -#define EXCCAUSE_INSTR_ADDR_ERROR 14 /* PIF Address Error on Instruction Fetch (RB-200x and later) */ -#define EXCCAUSE_LOAD_STORE_ADDR_ERROR 15 /* PIF Address Error on Load or Store (RB-200x and later) */ -#define EXCCAUSE_ITLB_MISS 16 /* ITLB Miss (no ITLB entry matches, hw refill also missed) */ -#define EXCCAUSE_ITLB_MULTIHIT 17 /* ITLB Multihit (multiple ITLB entries match) */ -#define EXCCAUSE_INSTR_RING 18 /* Ring Privilege Violation on Instruction Fetch */ -/* Reserved 19 */ /* Size Restriction on IFetch (not implemented) */ -#define EXCCAUSE_INSTR_PROHIBITED 20 /* Cache Attribute does not allow Instruction Fetch */ -/* Reserved 21..23 */ -#define EXCCAUSE_DTLB_MISS 24 /* DTLB Miss (no DTLB entry matches, hw refill also missed) */ -#define EXCCAUSE_DTLB_MULTIHIT 25 /* DTLB Multihit (multiple DTLB entries match) */ -#define EXCCAUSE_LOAD_STORE_RING 26 /* Ring Privilege Violation on Load or Store */ -/* Reserved 27 */ /* Size Restriction on Load/Store (not implemented) */ -#define EXCCAUSE_LOAD_PROHIBITED 28 /* Cache Attribute does not allow Load */ -#define EXCCAUSE_STORE_PROHIBITED 29 /* Cache Attribute does not allow Store */ -/* Reserved 30..31 */ -#define EXCCAUSE_CP_DISABLED(n) (32+(n)) /* Access to Coprocessor 'n' when disabled */ -#define EXCCAUSE_CP0_DISABLED 32 /* Access to Coprocessor 0 when disabled */ -#define EXCCAUSE_CP1_DISABLED 33 /* Access to Coprocessor 1 when disabled */ -#define EXCCAUSE_CP2_DISABLED 34 /* Access to Coprocessor 2 when disabled */ -#define EXCCAUSE_CP3_DISABLED 35 /* Access to Coprocessor 3 when disabled */ -#define EXCCAUSE_CP4_DISABLED 36 /* Access to Coprocessor 4 when disabled */ -#define EXCCAUSE_CP5_DISABLED 37 /* Access to Coprocessor 5 when disabled */ -#define EXCCAUSE_CP6_DISABLED 38 /* Access to Coprocessor 6 when disabled */ -#define EXCCAUSE_CP7_DISABLED 39 /* Access to Coprocessor 7 when disabled */ -/*#define EXCCAUSE_FLOATING_POINT 40*/ /* Floating Point Exception (not implemented) */ -/* Reserved 40..63 */ - -/* PS register fields: */ -#define PS_WOE_SHIFT 18 -#define PS_WOE_MASK 0x00040000 -#define PS_WOE PS_WOE_MASK -#define PS_CALLINC_SHIFT 16 -#define PS_CALLINC_MASK 0x00030000 -#define PS_CALLINC(n) (((n)&3)<4) 0 2 or >3 (TBD) - * T1030.0 0 1 (HAL beta) - * T1030.{1,2} 0 3 Equivalent to first release. - * T1030.n (n>=3) 0 >= 3 (TBD) - * T1040.n 1040 n Full CHAL available from T1040.2 - * T1050.n 1050 n . - * 6.0.n 6000 n Xtensa Tools v6 (RA-200x.n) - * 7.0.n 7000 n Xtensa Tools v7 (RB-200x.n) - * 7.1.n 7010 n Xtensa Tools v7.1 (RB-200x.(n+2)) - * - * - * Note: there is a distinction between the software version with - * which something is compiled (accessible using XTHAL_RELEASE_* macros) - * and the software version with which the HAL library was compiled - * (accessible using Xthal_release_* global variables). This - * distinction is particularly relevant for vendors that distribute - * configuration-independent binaries (eg. an OS), where their customer - * might link it with a HAL of a different Xtensa software version. - * In this case, it may be appropriate for the OS to verify at run-time - * whether XTHAL_RELEASE_* and Xthal_release_* are compatible. - * [Guidelines as to which version is compatible with which are not - * currently provided explicitly, but might be inferred from reading - * OSKit documentation for all releases -- compatibility is also highly - * dependent on which HAL features are used. Each version is usually - * backward compatible, with very few exceptions if any.] - * - * Notes: - * Tornado 2.0 supported in T1020.3+, T1030.1+, and T1040.{0,1} only. - * Tornado 2.0.2 supported in T1040.2+, T1050, and 6.0. - * Compile-time HAL port of NucleusPlus supported by T1040.2 and later. - */ - -/* Version comparison operators (among major/minor pairs): */ -#define XTHAL_REL_GE(maja,mina, majb,minb) ((maja) > (majb) || \ - ((maja) == (majb) && (mina) >= (minb))) -#define XTHAL_REL_GT(maja,mina, majb,minb) ((maja) > (majb) || \ - ((maja) == (majb) && (mina) > (minb))) -#define XTHAL_REL_LE(maja,mina, majb,minb) ((maja) < (majb) || \ - ((maja) == (majb) && (mina) <= (minb))) -#define XTHAL_REL_LT(maja,mina, majb,minb) ((maja) < (majb) || \ - ((maja) == (majb) && (mina) < (minb))) -#define XTHAL_REL_EQ(maja,mina, majb,minb) ((maja) == (majb) && (mina) == (minb)) - -/* Fuzzy (3-way) logic operators: */ -#define XTHAL_MAYBE -1 /* 0=NO, 1=YES, -1=MAYBE */ -#define XTHAL_FUZZY_AND(a,b) (((a)==0 || (b)==0) ? 0 : ((a)==1 && (b)==1) ? 1 : XTHAL_MAYBE) -#define XTHAL_FUZZY_OR(a,b) (((a)==1 || (b)==1) ? 1 : ((a)==0 && (b)==0) ? 0 : XTHAL_MAYBE) -#define XTHAL_FUZZY_NOT(a) (((a)==0 || (a)==1) ? (1-(a)) : XTHAL_MAYBE) - - -/* - * Architectural limit, independent of configuration: - */ -#define XTHAL_MAX_CPS 8 /* max number of coprocessors (0..7) */ - -/* Misc: */ -#define XTHAL_LITTLEENDIAN 0 -#define XTHAL_BIGENDIAN 1 - - - -#if !defined(_ASMLANGUAGE) && !defined(_NOCLANGUAGE) && !defined(__ASSEMBLER__) -#ifdef __cplusplus -extern "C" { -#endif - -/*---------------------------------------------------------------------- - HAL - ----------------------------------------------------------------------*/ - -/* Constant to be checked in build = (XTHAL_MAJOR_REV<<16)|XTHAL_MINOR_REV */ -extern const unsigned int Xthal_rev_no; - - -/*---------------------------------------------------------------------- - Optional/Custom Processor State - ----------------------------------------------------------------------*/ - -/* save & restore the extra processor state */ -extern void xthal_save_extra(void *base); -extern void xthal_restore_extra(void *base); - -extern void xthal_save_cpregs(void *base, int); -extern void xthal_restore_cpregs(void *base, int); -/* versions specific to each coprocessor id */ -extern void xthal_save_cp0(void *base); -extern void xthal_save_cp1(void *base); -extern void xthal_save_cp2(void *base); -extern void xthal_save_cp3(void *base); -extern void xthal_save_cp4(void *base); -extern void xthal_save_cp5(void *base); -extern void xthal_save_cp6(void *base); -extern void xthal_save_cp7(void *base); -extern void xthal_restore_cp0(void *base); -extern void xthal_restore_cp1(void *base); -extern void xthal_restore_cp2(void *base); -extern void xthal_restore_cp3(void *base); -extern void xthal_restore_cp4(void *base); -extern void xthal_restore_cp5(void *base); -extern void xthal_restore_cp6(void *base); -extern void xthal_restore_cp7(void *base); -/* pointers to each of the functions above */ -extern void* Xthal_cpregs_save_fn[XTHAL_MAX_CPS]; -extern void* Xthal_cpregs_restore_fn[XTHAL_MAX_CPS]; -/* similarly for non-windowed ABI (may be same or different) */ -extern void* Xthal_cpregs_save_nw_fn[XTHAL_MAX_CPS]; -extern void* Xthal_cpregs_restore_nw_fn[XTHAL_MAX_CPS]; - -/*extern void xthal_save_all_extra(void *base);*/ -/*extern void xthal_restore_all_extra(void *base);*/ - -/* space for processor state */ -extern const unsigned int Xthal_extra_size; -extern const unsigned int Xthal_extra_align; -extern const unsigned int Xthal_cpregs_size[XTHAL_MAX_CPS]; -extern const unsigned int Xthal_cpregs_align[XTHAL_MAX_CPS]; -extern const unsigned int Xthal_all_extra_size; -extern const unsigned int Xthal_all_extra_align; -/* coprocessor names */ -extern const char * const Xthal_cp_names[XTHAL_MAX_CPS]; - -/* initialize the extra processor */ -/*extern void xthal_init_extra(void);*/ -/* initialize the TIE coprocessor */ -/*extern void xthal_init_cp(int);*/ - -/* initialize the extra processor */ -extern void xthal_init_mem_extra(void *); -/* initialize the TIE coprocessor */ -extern void xthal_init_mem_cp(void *, int); - -/* the number of TIE coprocessors contiguous from zero (for Tor2) */ -extern const unsigned int Xthal_num_coprocessors; - -/* actual number of coprocessors */ -extern const unsigned char Xthal_cp_num; -/* index of highest numbered coprocessor, plus one */ -extern const unsigned char Xthal_cp_max; -/* index of highest allowed coprocessor number, per cfg, plus one */ -/*extern const unsigned char Xthal_cp_maxcfg;*/ -/* bitmask of which coprocessors are present */ -extern const unsigned int Xthal_cp_mask; - -/* read & write extra state register */ -/*extern int xthal_read_extra(void *base, unsigned reg, unsigned *value);*/ -/*extern int xthal_write_extra(void *base, unsigned reg, unsigned value);*/ - -/* read & write a TIE coprocessor register */ -/*extern int xthal_read_cpreg(void *base, int cp, unsigned reg, unsigned *value);*/ -/*extern int xthal_write_cpreg(void *base, int cp, unsigned reg, unsigned value);*/ - -/* return coprocessor number based on register */ -/*extern int xthal_which_cp(unsigned reg);*/ - - -/*---------------------------------------------------------------------- - Register Windows - ----------------------------------------------------------------------*/ - -/* number of registers in register window */ -extern const unsigned int Xthal_num_aregs; -extern const unsigned char Xthal_num_aregs_log2; - - -/*---------------------------------------------------------------------- - Cache - ----------------------------------------------------------------------*/ - -/* size of the cache lines in log2(bytes) */ -extern const unsigned char Xthal_icache_linewidth; -extern const unsigned char Xthal_dcache_linewidth; -/* size of the cache lines in bytes (2^linewidth) */ -extern const unsigned short Xthal_icache_linesize; -extern const unsigned short Xthal_dcache_linesize; - -/* size of the caches in bytes (ways * 2^(linewidth + setwidth)) */ -extern const unsigned int Xthal_icache_size; -extern const unsigned int Xthal_dcache_size; -/* cache features */ -extern const unsigned char Xthal_dcache_is_writeback; - -/* invalidate the caches */ -extern void xthal_icache_region_invalidate( void *addr, unsigned size ); -extern void xthal_dcache_region_invalidate( void *addr, unsigned size ); -extern void xthal_icache_line_invalidate(void *addr); -extern void xthal_dcache_line_invalidate(void *addr); -/* write dirty data back */ -extern void xthal_dcache_region_writeback( void *addr, unsigned size ); -extern void xthal_dcache_line_writeback(void *addr); -/* write dirty data back and invalidate */ -extern void xthal_dcache_region_writeback_inv( void *addr, unsigned size ); -extern void xthal_dcache_line_writeback_inv(void *addr); - -/* sync icache and memory */ -extern void xthal_icache_sync( void ); -/* sync dcache and memory */ -extern void xthal_dcache_sync( void ); - -/* coherency (low-level -- not normally called directly) */ -extern void xthal_cache_coherence_on( void ); -extern void xthal_cache_coherence_off( void ); -/* coherency (high-level) */ -extern void xthal_cache_coherence_optin( void ); -extern void xthal_cache_coherence_optout( void ); - -/* prefetch */ -#define XTHAL_PREFETCH_ENABLE -1 -#define XTHAL_PREFETCH_DISABLE 0 -extern int xthal_set_cache_prefetch( int ); -extern int xthal_get_cache_prefetch( void ); - - -/*---------------------------------------------------------------------- - Debug - ----------------------------------------------------------------------*/ - -/* 1 if debug option configured, 0 if not: */ -extern const int Xthal_debug_configured; - -/* Set (plant) and remove software breakpoint, both synchronizing cache: */ -extern unsigned int xthal_set_soft_break(void *addr); -extern void xthal_remove_soft_break(void *addr, unsigned int); - - -/*---------------------------------------------------------------------- - Disassembler - ----------------------------------------------------------------------*/ - -/* Max expected size of the return buffer for a disassembled instruction (hint only): */ -#define XTHAL_DISASM_BUFSIZE 80 - -/* Disassembly option bits for selecting what to return: */ -#define XTHAL_DISASM_OPT_ADDR 0x0001 /* display address */ -#define XTHAL_DISASM_OPT_OPHEX 0x0002 /* display opcode bytes in hex */ -#define XTHAL_DISASM_OPT_OPCODE 0x0004 /* display opcode name (mnemonic) */ -#define XTHAL_DISASM_OPT_PARMS 0x0008 /* display parameters */ -#define XTHAL_DISASM_OPT_ALL 0x0FFF /* display everything */ - -/* routine to get a string for the disassembled instruction */ -extern int xthal_disassemble( unsigned char *instr_buf, void *tgt_addr, - char *buffer, unsigned buflen, unsigned options ); - -/* routine to get the size of the next instruction. Returns 0 for - illegal instruction */ -extern int xthal_disassemble_size( unsigned char *instr_buf ); - - -/*---------------------------------------------------------------------- - Instruction/Data RAM/ROM Access - ----------------------------------------------------------------------*/ - -extern void* xthal_memcpy(void *dst, const void *src, unsigned len); -extern void* xthal_bcopy(const void *src, void *dst, unsigned len); - - -/*---------------------------------------------------------------------- - MP Synchronization - ----------------------------------------------------------------------*/ - -extern int xthal_compare_and_set( int *addr, int test_val, int compare_val ); - -/*extern const char Xthal_have_s32c1i;*/ - - -/*---------------------------------------------------------------------- - Miscellaneous - ----------------------------------------------------------------------*/ - -extern const unsigned int Xthal_release_major; -extern const unsigned int Xthal_release_minor; -extern const char * const Xthal_release_name; -extern const char * const Xthal_release_internal; - -extern const unsigned char Xthal_memory_order; -extern const unsigned char Xthal_have_windowed; -extern const unsigned char Xthal_have_density; -extern const unsigned char Xthal_have_booleans; -extern const unsigned char Xthal_have_loops; -extern const unsigned char Xthal_have_nsa; -extern const unsigned char Xthal_have_minmax; -extern const unsigned char Xthal_have_sext; -extern const unsigned char Xthal_have_clamps; -extern const unsigned char Xthal_have_mac16; -extern const unsigned char Xthal_have_mul16; -extern const unsigned char Xthal_have_fp; -extern const unsigned char Xthal_have_speculation; -extern const unsigned char Xthal_have_threadptr; - -extern const unsigned char Xthal_have_pif; -extern const unsigned short Xthal_num_writebuffer_entries; - -extern const unsigned int Xthal_build_unique_id; -/* Version info for hardware targeted by software upgrades: */ -extern const unsigned int Xthal_hw_configid0; -extern const unsigned int Xthal_hw_configid1; -extern const unsigned int Xthal_hw_release_major; -extern const unsigned int Xthal_hw_release_minor; -extern const char * const Xthal_hw_release_name; -extern const char * const Xthal_hw_release_internal; - -#ifdef __cplusplus -} -#endif -#endif /*!_ASMLANGUAGE && !_NOCLANGUAGE && !__ASSEMBLER__ */ - - - - - -/**************************************************************************** - Definitions Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code - ****************************************************************************/ - - -#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY - -/*---------------------------------------------------------------------- - Constant Definitions (shared with assembly) - ----------------------------------------------------------------------*/ - -/* - * Architectural limits, independent of configuration. - * Note that these are ISA-defined limits, not micro-architecture implementation - * limits enforced by the Xtensa Processor Generator (which may be stricter than - * these below). - */ -#define XTHAL_MAX_INTERRUPTS 32 /* max number of interrupts (0..31) */ -#define XTHAL_MAX_INTLEVELS 16 /* max number of interrupt levels (0..15) */ - /* (as of T1040, implementation limit is 7: 0..6) */ -#define XTHAL_MAX_TIMERS 4 /* max number of timers (CCOMPARE0..CCOMPARE3) */ - /* (as of T1040, implementation limit is 3: 0..2) */ - -/* Interrupt types: */ -#define XTHAL_INTTYPE_UNCONFIGURED 0 -#define XTHAL_INTTYPE_SOFTWARE 1 -#define XTHAL_INTTYPE_EXTERN_EDGE 2 -#define XTHAL_INTTYPE_EXTERN_LEVEL 3 -#define XTHAL_INTTYPE_TIMER 4 -#define XTHAL_INTTYPE_NMI 5 -#define XTHAL_INTTYPE_WRITE_ERROR 6 -#define XTHAL_MAX_INTTYPES 7 /* number of interrupt types */ - -/* Timer related: */ -#define XTHAL_TIMER_UNCONFIGURED -1 /* Xthal_timer_interrupt[] value for non-existent timers */ -#define XTHAL_TIMER_UNASSIGNED XTHAL_TIMER_UNCONFIGURED /* (for backwards compatibility only) */ - -/* Local Memory ECC/Parity: */ -#define XTHAL_MEMEP_PARITY 1 -#define XTHAL_MEMEP_ECC 2 -/* Flags parameter to xthal_memep_inject_error(): */ -#define XTHAL_MEMEP_F_LOCAL 0 /* local memory (default) */ -#define XTHAL_MEMEP_F_DCACHE_DATA 4 /* data cache data */ -#define XTHAL_MEMEP_F_DCACHE_TAG 5 /* data cache tag */ -#define XTHAL_MEMEP_F_ICACHE_DATA 6 /* instruction cache data */ -#define XTHAL_MEMEP_F_ICACHE_TAG 7 /* instruction cache tag */ -#define XTHAL_MEMEP_F_CORRECTABLE 16 /* inject correctable error - (default is non-corr.) */ - - -/* Access Mode bits (tentative): */ /* bit abbr unit short_name PPC equ - Description */ -#define XTHAL_AMB_EXCEPTION 0 /* 001 E EX fls: EXception none - exception on any access (aka "illegal") */ -#define XTHAL_AMB_HITCACHE 1 /* 002 C CH fls: use Cache on Hit ~(I CI) - [or H HC] way from tag match; - [or U UC] (ISA: same except Isolate case) */ -#define XTHAL_AMB_ALLOCATE 2 /* 004 A AL fl?: ALlocate none - [or F FI fill] refill cache on miss, way from LRU - (ISA: Read/Write Miss Refill) */ -#define XTHAL_AMB_WRITETHRU 3 /* 008 W WT --s: WriteThrough W WT - store immediately to memory (ISA: same) */ -#define XTHAL_AMB_ISOLATE 4 /* 010 I IS fls: ISolate none - use cache regardless of hit-vs-miss, - way from vaddr (ISA: use-cache-on-miss+hit) */ -#define XTHAL_AMB_GUARD 5 /* 020 G GU ?l?: GUard G * - non-speculative; spec/replay refs not permitted */ -#define XTHAL_AMB_COHERENT 6 /* 040 M MC ?ls: Mem/MP Coherent M - on read, other CPU/bus-master may need to supply data; - on write, maybe redirect to or flush other CPU dirty line; etc */ -#if 0 -#define XTHAL_AMB_ORDERED x /* 000 O OR fls: ORdered G * - mem accesses cannot be out of order */ -#define XTHAL_AMB_FUSEWRITES x /* 000 F FW --s: FuseWrites none - allow combining/merging/coalescing multiple writes - (to same datapath data unit) into one - (implied by writeback) */ -#define XTHAL_AMB_TRUSTED x /* 000 T TR ?l?: TRusted none - memory will not bus error (if it does, - handle as fatal imprecise interrupt) */ -#define XTHAL_AMB_PREFETCH x /* 000 P PR fl?: PRefetch none - on refill, read line+1 into prefetch buffers */ -#define XTHAL_AMB_STREAM x /* 000 S ST ???: STreaming none - access one of N stream buffers */ -#endif /*0*/ - -#define XTHAL_AM_EXCEPTION (1< = bit is set - * '-' = bit is clear - * '.' = bit is irrelevant / don't care, as follows: - * E=1 makes all others irrelevant - * W,F relevant only for stores - * "2345" - * Indicates which Xtensa releases support the corresponding - * access mode. Releases for each character column are: - * 2 = prior to T1020.2: T1015 (V1.5), T1020.0, T1020.1 - * 3 = T1020.2 and later: T1020.2+, T1030 - * 4 = T1040 - * 5 = T1050 (maybe), LX1, LX2, LX2.1 - * 7 = LX2.2 - * 8 = LX3.0 - * And the character column contents are: - * = supported by release(s) - * "." = unsupported by release(s) - * "?" = support unknown - */ - /* FOMGIWACE 234578 */ -/* For instruction fetch: */ -#define XTHAL_FAM_EXCEPTION 0x001 /* ........E 234578 exception */ -/*efine XTHAL_FAM_ISOLATE*/ /*0x012*/ /* .---I.-C- ...... isolate */ -#define XTHAL_FAM_BYPASS 0x000 /* .----.--- 234578 bypass */ -/*efine XTHAL_FAM_NACACHED*/ /*0x002*/ /* .----.-C- ...... cached no-allocate (frozen) */ -#define XTHAL_FAM_CACHED 0x006 /* .----.AC- 234578 cached */ -/* For data load: */ -#define XTHAL_LAM_EXCEPTION 0x001 /* ........E 234578 exception */ -#define XTHAL_LAM_ISOLATE 0x012 /* .---I.-C- 234578 isolate */ -#define XTHAL_LAM_BYPASS 0x000 /* .O---.--- 2..... bypass speculative */ -#define XTHAL_LAM_BYPASSG 0x020 /* .O-G-.--- .34578 bypass guarded */ -#define XTHAL_LAM_CACHED_NOALLOC 0x002 /* .O---.-C- 234578 cached no-allocate speculative */ -#define XTHAL_LAM_NACACHED XTHAL_LAM_CACHED_NOALLOC -#define XTHAL_LAM_NACACHEDG 0x022 /* .O-G-.-C- .?.... cached no-allocate guarded */ -#define XTHAL_LAM_CACHED 0x006 /* .----.AC- 234578 cached speculative */ -#define XTHAL_LAM_COHCACHED 0x046 /* .-M--.AC- ....*8 cached speculative MP-coherent */ -/* For data store: */ -#define XTHAL_SAM_EXCEPTION 0x001 /* ........E 234578 exception */ -#define XTHAL_SAM_ISOLATE 0x032 /* .--GI--C- 234578 isolate */ -#define XTHAL_SAM_BYPASS 0x028 /* -O-G-W--- 234578 bypass */ -#define XTHAL_SAM_WRITETHRU 0x02A /* -O-G-W-C- 234578 writethrough */ -/*efine XTHAL_SAM_WRITETHRU_ALLOC*/ /*0x02E*/ /* -O-G-WAC- ...... writethrough allocate */ -#define XTHAL_SAM_WRITEBACK 0x026 /* F-MG--AC- ...578 writeback */ -#define XTHAL_SAM_COHWRITEBACK 0x066 /* F-MG--AC- ....*8 writeback MP-coherent */ -#define XTHAL_SAM_WRITEBACK_NOALLOC 0x022 /* ?--G---C- .....8 writeback no-allocate */ - -#if 0 -/* - Cache attribute encoding for CACHEATTR (per ISA): - (Note: if this differs from ISA Ref Manual, ISA has precedence) - - Inst-fetches Loads Stores - ------------- ------------ ------------- -0x0 FCA_EXCEPTION LCA_NACACHED SCA_WRITETHRU cached no-allocate (previously misnamed "uncached") -0x1 FCA_CACHED LCA_CACHED SCA_WRITETHRU cached -0x2 FCA_BYPASS LCA_BYPASS_G* SCA_BYPASS bypass cache (what most people call uncached) -0x3 FCA_CACHED LCA_CACHED SCA_WRITEALLOCF write-allocate - or LCA_EXCEPTION SCA_EXCEPTION (if unimplemented) -0x4 FCA_CACHED LCA_CACHED SCA_WRITEBACK[M] write-back [MP-coherent] - or LCA_EXCEPTION SCA_EXCEPTION (if unimplemented) -0x5 FCA_CACHED LCA_CACHED SCA_WRITEBACK_NOALLOC write-back no-allocate - or FCA_EXCEPTION LCA_EXCEPTION SCA_EXCEPTION (if unimplemented) -0x6..D FCA_EXCEPTION LCA_EXCEPTION SCA_EXCEPTION (reserved) -0xE FCA_EXCEPTION LCA_ISOLATE SCA_ISOLATE isolate -0xF FCA_EXCEPTION LCA_EXCEPTION SCA_EXCEPTION illegal - * Prior to T1020.2?, guard feature not supported, this defaulted to speculative (no _G) -*/ -#endif /*0*/ - - -#if !defined(_ASMLANGUAGE) && !defined(_NOCLANGUAGE) && !defined(__ASSEMBLER__) -#ifdef __cplusplus -extern "C" { -#endif - - -/*---------------------------------------------------------------------- - Register Windows - ----------------------------------------------------------------------*/ - -/* This spill any live register windows (other than the caller's): - * (NOTE: current implementation require privileged code, but - * a user-callable implementation is possible.) */ -extern void xthal_window_spill( void ); - - -/*---------------------------------------------------------------------- - Optional/Custom Processor State - ----------------------------------------------------------------------*/ - -/* validate & invalidate the TIE register file */ -extern void xthal_validate_cp(int); -extern void xthal_invalidate_cp(int); - -/* read and write cpenable register */ -extern void xthal_set_cpenable(unsigned); -extern unsigned xthal_get_cpenable(void); - - -/*---------------------------------------------------------------------- - Interrupts - ----------------------------------------------------------------------*/ - -/* the number of interrupt levels */ -extern const unsigned char Xthal_num_intlevels; -/* the number of interrupts */ -extern const unsigned char Xthal_num_interrupts; - -/* mask for level of interrupts */ -extern const unsigned int Xthal_intlevel_mask[XTHAL_MAX_INTLEVELS]; -/* mask for level 0 to N interrupts */ -extern const unsigned int Xthal_intlevel_andbelow_mask[XTHAL_MAX_INTLEVELS]; - -/* level of each interrupt */ -extern const unsigned char Xthal_intlevel[XTHAL_MAX_INTERRUPTS]; - -/* type per interrupt */ -extern const unsigned char Xthal_inttype[XTHAL_MAX_INTERRUPTS]; - -/* masks of each type of interrupt */ -extern const unsigned int Xthal_inttype_mask[XTHAL_MAX_INTTYPES]; - -/* interrupt numbers assigned to each timer interrupt */ -extern const int Xthal_timer_interrupt[XTHAL_MAX_TIMERS]; - -/* INTENABLE,INTERRUPT,INTSET,INTCLEAR register access functions: */ -extern unsigned xthal_get_intenable( void ); -extern void xthal_set_intenable( unsigned ); -extern unsigned xthal_get_interrupt( void ); -#define xthal_get_intread xthal_get_interrupt /* backward compatibility */ -extern void xthal_set_intset( unsigned ); -extern void xthal_set_intclear( unsigned ); - - -/*---------------------------------------------------------------------- - Debug - ----------------------------------------------------------------------*/ - -/* Number of instruction and data break registers: */ -extern const int Xthal_num_ibreak; -extern const int Xthal_num_dbreak; - - -/*---------------------------------------------------------------------- - Core Counter - ----------------------------------------------------------------------*/ - -/* counter info */ -extern const unsigned char Xthal_have_ccount; /* set if CCOUNT register present */ -extern const unsigned char Xthal_num_ccompare; /* number of CCOMPAREn registers */ - -/* get CCOUNT register (if not present return 0) */ -extern unsigned xthal_get_ccount(void); - -/* set and get CCOMPAREn registers (if not present, get returns 0) */ -extern void xthal_set_ccompare(int, unsigned); -extern unsigned xthal_get_ccompare(int); - - -/*---------------------------------------------------------------------- - Miscellaneous - ----------------------------------------------------------------------*/ - -extern const unsigned char Xthal_have_prid; -extern const unsigned char Xthal_have_exceptions; -extern const unsigned char Xthal_xea_version; -extern const unsigned char Xthal_have_interrupts; -extern const unsigned char Xthal_have_highlevel_interrupts; -extern const unsigned char Xthal_have_nmi; - -extern unsigned xthal_get_prid( void ); - - -/*---------------------------------------------------------------------- - Virtual interrupt prioritization (DEPRECATED) - ----------------------------------------------------------------------*/ - -/* Convert between interrupt levels (as per PS.INTLEVEL) and virtual interrupt priorities: */ -extern unsigned xthal_vpri_to_intlevel(unsigned vpri); -extern unsigned xthal_intlevel_to_vpri(unsigned intlevel); - -/* Enables/disables given set (mask) of interrupts; returns previous enabled-mask of all ints: */ -extern unsigned xthal_int_enable(unsigned); -extern unsigned xthal_int_disable(unsigned); - -/* Set/get virtual priority of an interrupt: */ -extern int xthal_set_int_vpri(int intnum, int vpri); -extern int xthal_get_int_vpri(int intnum); - -/* Set/get interrupt lockout level for exclusive access to virtual priority data structures: */ -extern void xthal_set_vpri_locklevel(unsigned intlevel); -extern unsigned xthal_get_vpri_locklevel(void); - -/* Set/get current virtual interrupt priority: */ -extern unsigned xthal_set_vpri(unsigned vpri); -extern unsigned xthal_get_vpri(void); -extern unsigned xthal_set_vpri_intlevel(unsigned intlevel); -extern unsigned xthal_set_vpri_lock(void); - - -/*---------------------------------------------------------------------- - Generic Interrupt Trampolining Support (DEPRECATED) - ----------------------------------------------------------------------*/ - -typedef void (XtHalVoidFunc)(void); - -/* Bitmask of interrupts currently trampolining down: */ -extern unsigned Xthal_tram_pending; - -/* - * Bitmask of which interrupts currently trampolining down synchronously are - * actually enabled; this bitmask is necessary because INTENABLE cannot hold - * that state (sync-trampolining interrupts must be kept disabled while - * trampolining); in the current implementation, any bit set here is not set - * in INTENABLE, and vice-versa; once a sync-trampoline is handled (at level - * one), its enable bit must be moved from here to INTENABLE: - */ -extern unsigned Xthal_tram_enabled; - -/* Bitmask of interrupts configured for sync trampolining: */ -extern unsigned Xthal_tram_sync; - -/* Trampoline support functions: */ -extern unsigned xthal_tram_pending_to_service( void ); -extern void xthal_tram_done( unsigned serviced_mask ); -extern int xthal_tram_set_sync( int intnum, int sync ); -extern XtHalVoidFunc* xthal_set_tram_trigger_func( XtHalVoidFunc *trigger_fn ); - - -/*---------------------------------------------------------------------- - Internal Memories - ----------------------------------------------------------------------*/ - -extern const unsigned char Xthal_num_instrom; -extern const unsigned char Xthal_num_instram; -extern const unsigned char Xthal_num_datarom; -extern const unsigned char Xthal_num_dataram; -extern const unsigned char Xthal_num_xlmi; - -/* Each of the following arrays contains at least one entry, - * or as many entries as needed if more than one: */ -extern const unsigned int Xthal_instrom_vaddr[]; -extern const unsigned int Xthal_instrom_paddr[]; -extern const unsigned int Xthal_instrom_size []; -extern const unsigned int Xthal_instram_vaddr[]; -extern const unsigned int Xthal_instram_paddr[]; -extern const unsigned int Xthal_instram_size []; -extern const unsigned int Xthal_datarom_vaddr[]; -extern const unsigned int Xthal_datarom_paddr[]; -extern const unsigned int Xthal_datarom_size []; -extern const unsigned int Xthal_dataram_vaddr[]; -extern const unsigned int Xthal_dataram_paddr[]; -extern const unsigned int Xthal_dataram_size []; -extern const unsigned int Xthal_xlmi_vaddr[]; -extern const unsigned int Xthal_xlmi_paddr[]; -extern const unsigned int Xthal_xlmi_size []; - - -/*---------------------------------------------------------------------- - Cache - ----------------------------------------------------------------------*/ - -/* number of cache sets in log2(lines per way) */ -extern const unsigned char Xthal_icache_setwidth; -extern const unsigned char Xthal_dcache_setwidth; -/* cache set associativity (number of ways) */ -extern const unsigned int Xthal_icache_ways; -extern const unsigned int Xthal_dcache_ways; -/* cache features */ -extern const unsigned char Xthal_icache_line_lockable; -extern const unsigned char Xthal_dcache_line_lockable; - -/* cache attribute register control (used by other HAL routines) */ -extern unsigned xthal_get_cacheattr( void ); -extern unsigned xthal_get_icacheattr( void ); -extern unsigned xthal_get_dcacheattr( void ); -extern void xthal_set_cacheattr( unsigned ); -extern void xthal_set_icacheattr( unsigned ); -extern void xthal_set_dcacheattr( unsigned ); -/* set cache attribute (access modes) for a range of memory */ -extern int xthal_set_region_attribute( void *addr, unsigned size, - unsigned cattr, unsigned flags ); -/* Bits of flags parameter to xthal_set_region_attribute(): */ -#define XTHAL_CAFLAG_EXPAND 0x000100 /* only expand allowed access to range, don't reduce it */ -#define XTHAL_CAFLAG_EXACT 0x000200 /* return error if can't apply change to exact range specified */ -#define XTHAL_CAFLAG_NO_PARTIAL 0x000400 /* don't apply change to regions partially covered by range */ -#define XTHAL_CAFLAG_NO_AUTO_WB 0x000800 /* don't writeback data after leaving writeback attribute */ -#define XTHAL_CAFLAG_NO_AUTO_INV 0x001000 /* don't invalidate after disabling cache (entering bypass) */ - -/* enable caches */ -extern void xthal_icache_enable( void ); /* DEPRECATED */ -extern void xthal_dcache_enable( void ); /* DEPRECATED */ -/* disable caches */ -extern void xthal_icache_disable( void ); /* DEPRECATED */ -extern void xthal_dcache_disable( void ); /* DEPRECATED */ - -/* invalidate the caches */ -extern void xthal_icache_all_invalidate( void ); -extern void xthal_dcache_all_invalidate( void ); -/* write dirty data back */ -extern void xthal_dcache_all_writeback( void ); -/* write dirty data back and invalidate */ -extern void xthal_dcache_all_writeback_inv( void ); -/* prefetch and lock specified memory range into cache */ -extern void xthal_icache_region_lock( void *addr, unsigned size ); -extern void xthal_dcache_region_lock( void *addr, unsigned size ); -extern void xthal_icache_line_lock(void *addr); -extern void xthal_dcache_line_lock(void *addr); -/* unlock from cache */ -extern void xthal_icache_all_unlock( void ); -extern void xthal_dcache_all_unlock( void ); -extern void xthal_icache_region_unlock( void *addr, unsigned size ); -extern void xthal_dcache_region_unlock( void *addr, unsigned size ); -extern void xthal_icache_line_unlock(void *addr); -extern void xthal_dcache_line_unlock(void *addr); - - - -/*---------------------------------------------------------------------- - Local Memory ECC/Parity - ----------------------------------------------------------------------*/ - -/* Inject memory errors; flags is bit combination of XTHAL_MEMEP_F_xxx: */ -extern void xthal_memep_inject_error(void *addr, int size, int flags); - - - -/*---------------------------------------------------------------------- - Memory Management Unit - ----------------------------------------------------------------------*/ - -extern const unsigned char Xthal_have_spanning_way; -extern const unsigned char Xthal_have_identity_map; -extern const unsigned char Xthal_have_mimic_cacheattr; -extern const unsigned char Xthal_have_xlt_cacheattr; -extern const unsigned char Xthal_have_cacheattr; -extern const unsigned char Xthal_have_tlbs; - -extern const unsigned char Xthal_mmu_asid_bits; /* 0 .. 8 */ -extern const unsigned char Xthal_mmu_asid_kernel; -extern const unsigned char Xthal_mmu_rings; /* 1 .. 4 (perhaps 0 if no MMU and/or no protection?) */ -extern const unsigned char Xthal_mmu_ring_bits; -extern const unsigned char Xthal_mmu_sr_bits; -extern const unsigned char Xthal_mmu_ca_bits; -extern const unsigned int Xthal_mmu_max_pte_page_size; -extern const unsigned int Xthal_mmu_min_pte_page_size; - -extern const unsigned char Xthal_itlb_way_bits; -extern const unsigned char Xthal_itlb_ways; -extern const unsigned char Xthal_itlb_arf_ways; -extern const unsigned char Xthal_dtlb_way_bits; -extern const unsigned char Xthal_dtlb_ways; -extern const unsigned char Xthal_dtlb_arf_ways; - -/* Convert between virtual and physical addresses (through static maps only): */ -/*** WARNING: these two functions may go away in a future release; don't depend on them! ***/ -extern int xthal_static_v2p( unsigned vaddr, unsigned *paddrp ); -extern int xthal_static_p2v( unsigned paddr, unsigned *vaddrp, unsigned cached ); - - -#ifdef __cplusplus -} -#endif -#endif /*!_ASMLANGUAGE && !_NOCLANGUAGE && !__ASSEMBLER__ */ - -#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ - - - - -/**************************************************************************** - EXPERIMENTAL and DEPRECATED Definitions - ****************************************************************************/ - - -#if !defined(_ASMLANGUAGE) && !defined(_NOCLANGUAGE) && !defined(__ASSEMBLER__) -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef INCLUDE_DEPRECATED_HAL_CODE -extern const unsigned char Xthal_have_old_exc_arch; -extern const unsigned char Xthal_have_mmu; -extern const unsigned int Xthal_num_regs; -extern const unsigned char Xthal_num_iroms; -extern const unsigned char Xthal_num_irams; -extern const unsigned char Xthal_num_droms; -extern const unsigned char Xthal_num_drams; -extern const unsigned int Xthal_configid0; -extern const unsigned int Xthal_configid1; -#endif - -#ifdef INCLUDE_DEPRECATED_HAL_DEBUG_CODE -#define XTHAL_24_BIT_BREAK 0x80000000 -#define XTHAL_16_BIT_BREAK 0x40000000 -extern const unsigned short Xthal_ill_inst_16[16]; -#define XTHAL_DEST_REG 0xf0000000 /* Mask for destination register */ -#define XTHAL_DEST_REG_INST 0x08000000 /* Branch address is in register */ -#define XTHAL_DEST_REL_INST 0x04000000 /* Branch address is relative */ -#define XTHAL_RFW_INST 0x00000800 -#define XTHAL_RFUE_INST 0x00000400 -#define XTHAL_RFI_INST 0x00000200 -#define XTHAL_RFE_INST 0x00000100 -#define XTHAL_RET_INST 0x00000080 -#define XTHAL_BREAK_INST 0x00000040 -#define XTHAL_SYSCALL_INST 0x00000020 -#define XTHAL_LOOP_END 0x00000010 /* Not set by xthal_inst_type */ -#define XTHAL_JUMP_INST 0x00000008 /* Call or jump instruction */ -#define XTHAL_BRANCH_INST 0x00000004 /* Branch instruction */ -#define XTHAL_24_BIT_INST 0x00000002 -#define XTHAL_16_BIT_INST 0x00000001 -typedef struct xthal_state { - unsigned pc; - unsigned ar[16]; - unsigned lbeg; - unsigned lend; - unsigned lcount; - unsigned extra_ptr; - unsigned cpregs_ptr[XTHAL_MAX_CPS]; -} XTHAL_STATE; -extern unsigned int xthal_inst_type(void *addr); -extern unsigned int xthal_branch_addr(void *addr); -extern unsigned int xthal_get_npc(XTHAL_STATE *user_state); -#endif /* INCLUDE_DEPRECATED_HAL_DEBUG_CODE */ - -#ifdef __cplusplus -} -#endif -#endif /*!_ASMLANGUAGE && !_NOCLANGUAGE && !__ASSEMBLER__ */ - -#endif /*XTENSA_HAL_H*/ - +/* + xtensa/hal.h -- contains a definition of the Core HAL interface + + All definitions in this header file are independent of any specific + Xtensa processor configuration. Thus software (eg. OS, application, + etc) can include this header file and be compiled into configuration- + independent objects that can be distributed and eventually linked + to the HAL library (libhal.a) to create a configuration-specific + final executable. + + Certain definitions, however, are release/version-specific -- such as + the XTHAL_RELEASE_xxx macros (or additions made in later versions). + + + $Id: //depot/rel/Boreal/Xtensa/OS/target-os-src/hal.h.tpp#3 $ + + Copyright (c) 1999-2010 Tensilica Inc. + + 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 XTENSA_HAL_H +#define XTENSA_HAL_H + + +/**************************************************************************** + Definitions Useful for Any Code, USER or PRIVILEGED + ****************************************************************************/ + + +/*---------------------------------------------------------------------- + Constant Definitions (shared with assembly) + ----------------------------------------------------------------------*/ + +/* + * Software (Xtensa Tools) version information. Not configuration-specific! + * + * NOTE: "release" is a misnomer here, these are really product "version" + * numbers. A "release" is a collection of product versions + * made available at once (together) to customers. + * In the past, release and version names all matched in T####.# form, + * making the distinction irrelevant. This is no longer the case. + */ +#define XTHAL_RELEASE_MAJOR 8000 +#define XTHAL_RELEASE_MINOR 1 +#define XTHAL_RELEASE_NAME "8.0.1" +#define XTHAL_REL_8 1 +#define XTHAL_REL_8_0 1 +#define XTHAL_REL_8_0_1 1 + +/* HAL version numbers (these names are for backward compatibility): */ +#define XTHAL_MAJOR_REV XTHAL_RELEASE_MAJOR +#define XTHAL_MINOR_REV XTHAL_RELEASE_MINOR +/* + * A bit of software release/version history on values of XTHAL_{MAJOR,MINOR}_REV: + * + * SW Version MAJOR MINOR Comment + * ======= ===== ===== ======= + * T1015.n n/a n/a (HAL not yet available) + * T1020.{0,1,2} 0 1 (HAL beta) + * T1020.{3,4} 0 2 First release. + * T1020.n (n>4) 0 2 or >3 (TBD) + * T1030.0 0 1 (HAL beta) + * T1030.{1,2} 0 3 Equivalent to first release. + * T1030.n (n>=3) 0 >= 3 (TBD) + * T1040.n 1040 n Full CHAL available from T1040.2 + * T1050.n 1050 n . + * 6.0.n 6000 n Xtensa Tools v6 (RA-200x.n) + * 7.0.n 7000 n Xtensa Tools v7 (RB-200x.n) + * 7.1.n 7010 n Xtensa Tools v7.1 (RB-200x.(n+2)) + * + * + * Note: there is a distinction between the software version with + * which something is compiled (accessible using XTHAL_RELEASE_* macros) + * and the software version with which the HAL library was compiled + * (accessible using Xthal_release_* global variables). This + * distinction is particularly relevant for vendors that distribute + * configuration-independent binaries (eg. an OS), where their customer + * might link it with a HAL of a different Xtensa software version. + * In this case, it may be appropriate for the OS to verify at run-time + * whether XTHAL_RELEASE_* and Xthal_release_* are compatible. + * [Guidelines as to which version is compatible with which are not + * currently provided explicitly, but might be inferred from reading + * OSKit documentation for all releases -- compatibility is also highly + * dependent on which HAL features are used. Each version is usually + * backward compatible, with very few exceptions if any.] + * + * Notes: + * Tornado 2.0 supported in T1020.3+, T1030.1+, and T1040.{0,1} only. + * Tornado 2.0.2 supported in T1040.2+, T1050, and 6.0. + * Compile-time HAL port of NucleusPlus supported by T1040.2 and later. + */ + +/* Version comparison operators (among major/minor pairs): */ +#define XTHAL_REL_GE(maja,mina, majb,minb) ((maja) > (majb) || \ + ((maja) == (majb) && (mina) >= (minb))) +#define XTHAL_REL_GT(maja,mina, majb,minb) ((maja) > (majb) || \ + ((maja) == (majb) && (mina) > (minb))) +#define XTHAL_REL_LE(maja,mina, majb,minb) ((maja) < (majb) || \ + ((maja) == (majb) && (mina) <= (minb))) +#define XTHAL_REL_LT(maja,mina, majb,minb) ((maja) < (majb) || \ + ((maja) == (majb) && (mina) < (minb))) +#define XTHAL_REL_EQ(maja,mina, majb,minb) ((maja) == (majb) && (mina) == (minb)) + +/* Fuzzy (3-way) logic operators: */ +#define XTHAL_MAYBE -1 /* 0=NO, 1=YES, -1=MAYBE */ +#define XTHAL_FUZZY_AND(a,b) (((a)==0 || (b)==0) ? 0 : ((a)==1 && (b)==1) ? 1 : XTHAL_MAYBE) +#define XTHAL_FUZZY_OR(a,b) (((a)==1 || (b)==1) ? 1 : ((a)==0 && (b)==0) ? 0 : XTHAL_MAYBE) +#define XTHAL_FUZZY_NOT(a) (((a)==0 || (a)==1) ? (1-(a)) : XTHAL_MAYBE) + + +/* + * Architectural limit, independent of configuration: + */ +#define XTHAL_MAX_CPS 8 /* max number of coprocessors (0..7) */ + +/* Misc: */ +#define XTHAL_LITTLEENDIAN 0 +#define XTHAL_BIGENDIAN 1 + + + +#if !defined(_ASMLANGUAGE) && !defined(_NOCLANGUAGE) && !defined(__ASSEMBLER__) +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------------------------------------------------- + HAL + ----------------------------------------------------------------------*/ + +/* Constant to be checked in build = (XTHAL_MAJOR_REV<<16)|XTHAL_MINOR_REV */ +extern const unsigned int Xthal_rev_no; + + +/*---------------------------------------------------------------------- + Optional/Custom Processor State + ----------------------------------------------------------------------*/ + +/* save & restore the extra processor state */ +extern void xthal_save_extra(void *base); +extern void xthal_restore_extra(void *base); + +extern void xthal_save_cpregs(void *base, int); +extern void xthal_restore_cpregs(void *base, int); +/* versions specific to each coprocessor id */ +extern void xthal_save_cp0(void *base); +extern void xthal_save_cp1(void *base); +extern void xthal_save_cp2(void *base); +extern void xthal_save_cp3(void *base); +extern void xthal_save_cp4(void *base); +extern void xthal_save_cp5(void *base); +extern void xthal_save_cp6(void *base); +extern void xthal_save_cp7(void *base); +extern void xthal_restore_cp0(void *base); +extern void xthal_restore_cp1(void *base); +extern void xthal_restore_cp2(void *base); +extern void xthal_restore_cp3(void *base); +extern void xthal_restore_cp4(void *base); +extern void xthal_restore_cp5(void *base); +extern void xthal_restore_cp6(void *base); +extern void xthal_restore_cp7(void *base); +/* pointers to each of the functions above */ +extern void* Xthal_cpregs_save_fn[XTHAL_MAX_CPS]; +extern void* Xthal_cpregs_restore_fn[XTHAL_MAX_CPS]; +/* similarly for non-windowed ABI (may be same or different) */ +extern void* Xthal_cpregs_save_nw_fn[XTHAL_MAX_CPS]; +extern void* Xthal_cpregs_restore_nw_fn[XTHAL_MAX_CPS]; + +/*extern void xthal_save_all_extra(void *base);*/ +/*extern void xthal_restore_all_extra(void *base);*/ + +/* space for processor state */ +extern const unsigned int Xthal_extra_size; +extern const unsigned int Xthal_extra_align; +extern const unsigned int Xthal_cpregs_size[XTHAL_MAX_CPS]; +extern const unsigned int Xthal_cpregs_align[XTHAL_MAX_CPS]; +extern const unsigned int Xthal_all_extra_size; +extern const unsigned int Xthal_all_extra_align; +/* coprocessor names */ +extern const char * const Xthal_cp_names[XTHAL_MAX_CPS]; + +/* initialize the extra processor */ +/*extern void xthal_init_extra(void);*/ +/* initialize the TIE coprocessor */ +/*extern void xthal_init_cp(int);*/ + +/* initialize the extra processor */ +extern void xthal_init_mem_extra(void *); +/* initialize the TIE coprocessor */ +extern void xthal_init_mem_cp(void *, int); + +/* the number of TIE coprocessors contiguous from zero (for Tor2) */ +extern const unsigned int Xthal_num_coprocessors; + +/* actual number of coprocessors */ +extern const unsigned char Xthal_cp_num; +/* index of highest numbered coprocessor, plus one */ +extern const unsigned char Xthal_cp_max; +/* index of highest allowed coprocessor number, per cfg, plus one */ +/*extern const unsigned char Xthal_cp_maxcfg;*/ +/* bitmask of which coprocessors are present */ +extern const unsigned int Xthal_cp_mask; + +/* read & write extra state register */ +/*extern int xthal_read_extra(void *base, unsigned reg, unsigned *value);*/ +/*extern int xthal_write_extra(void *base, unsigned reg, unsigned value);*/ + +/* read & write a TIE coprocessor register */ +/*extern int xthal_read_cpreg(void *base, int cp, unsigned reg, unsigned *value);*/ +/*extern int xthal_write_cpreg(void *base, int cp, unsigned reg, unsigned value);*/ + +/* return coprocessor number based on register */ +/*extern int xthal_which_cp(unsigned reg);*/ + + +/*---------------------------------------------------------------------- + Register Windows + ----------------------------------------------------------------------*/ + +/* number of registers in register window */ +extern const unsigned int Xthal_num_aregs; +extern const unsigned char Xthal_num_aregs_log2; + + +/*---------------------------------------------------------------------- + Cache + ----------------------------------------------------------------------*/ + +/* size of the cache lines in log2(bytes) */ +extern const unsigned char Xthal_icache_linewidth; +extern const unsigned char Xthal_dcache_linewidth; +/* size of the cache lines in bytes (2^linewidth) */ +extern const unsigned short Xthal_icache_linesize; +extern const unsigned short Xthal_dcache_linesize; + +/* size of the caches in bytes (ways * 2^(linewidth + setwidth)) */ +extern const unsigned int Xthal_icache_size; +extern const unsigned int Xthal_dcache_size; +/* cache features */ +extern const unsigned char Xthal_dcache_is_writeback; + +/* invalidate the caches */ +extern void xthal_icache_region_invalidate( void *addr, unsigned size ); +extern void xthal_dcache_region_invalidate( void *addr, unsigned size ); +extern void xthal_icache_line_invalidate(void *addr); +extern void xthal_dcache_line_invalidate(void *addr); +/* write dirty data back */ +extern void xthal_dcache_region_writeback( void *addr, unsigned size ); +extern void xthal_dcache_line_writeback(void *addr); +/* write dirty data back and invalidate */ +extern void xthal_dcache_region_writeback_inv( void *addr, unsigned size ); +extern void xthal_dcache_line_writeback_inv(void *addr); + +/* sync icache and memory */ +extern void xthal_icache_sync( void ); +/* sync dcache and memory */ +extern void xthal_dcache_sync( void ); + +/* coherency (low-level -- not normally called directly) */ +extern void xthal_cache_coherence_on( void ); +extern void xthal_cache_coherence_off( void ); +/* coherency (high-level) */ +extern void xthal_cache_coherence_optin( void ); +extern void xthal_cache_coherence_optout( void ); + +/* prefetch */ +#define XTHAL_PREFETCH_ENABLE -1 +#define XTHAL_PREFETCH_DISABLE 0 +extern int xthal_set_cache_prefetch( int ); +extern int xthal_get_cache_prefetch( void ); + + +/*---------------------------------------------------------------------- + Debug + ----------------------------------------------------------------------*/ + +/* 1 if debug option configured, 0 if not: */ +extern const int Xthal_debug_configured; + +/* Set (plant) and remove software breakpoint, both synchronizing cache: */ +extern unsigned int xthal_set_soft_break(void *addr); +extern void xthal_remove_soft_break(void *addr, unsigned int); + + +/*---------------------------------------------------------------------- + Disassembler + ----------------------------------------------------------------------*/ + +/* Max expected size of the return buffer for a disassembled instruction (hint only): */ +#define XTHAL_DISASM_BUFSIZE 80 + +/* Disassembly option bits for selecting what to return: */ +#define XTHAL_DISASM_OPT_ADDR 0x0001 /* display address */ +#define XTHAL_DISASM_OPT_OPHEX 0x0002 /* display opcode bytes in hex */ +#define XTHAL_DISASM_OPT_OPCODE 0x0004 /* display opcode name (mnemonic) */ +#define XTHAL_DISASM_OPT_PARMS 0x0008 /* display parameters */ +#define XTHAL_DISASM_OPT_ALL 0x0FFF /* display everything */ + +/* routine to get a string for the disassembled instruction */ +extern int xthal_disassemble( unsigned char *instr_buf, void *tgt_addr, + char *buffer, unsigned buflen, unsigned options ); + +/* routine to get the size of the next instruction. Returns 0 for + illegal instruction */ +extern int xthal_disassemble_size( unsigned char *instr_buf ); + + +/*---------------------------------------------------------------------- + Instruction/Data RAM/ROM Access + ----------------------------------------------------------------------*/ + +extern void* xthal_memcpy(void *dst, const void *src, unsigned len); +extern void* xthal_bcopy(const void *src, void *dst, unsigned len); + + +/*---------------------------------------------------------------------- + MP Synchronization + ----------------------------------------------------------------------*/ + +extern int xthal_compare_and_set( int *addr, int test_val, int compare_val ); + +/*extern const char Xthal_have_s32c1i;*/ + + +/*---------------------------------------------------------------------- + Miscellaneous + ----------------------------------------------------------------------*/ + +extern const unsigned int Xthal_release_major; +extern const unsigned int Xthal_release_minor; +extern const char * const Xthal_release_name; +extern const char * const Xthal_release_internal; + +extern const unsigned char Xthal_memory_order; +extern const unsigned char Xthal_have_windowed; +extern const unsigned char Xthal_have_density; +extern const unsigned char Xthal_have_booleans; +extern const unsigned char Xthal_have_loops; +extern const unsigned char Xthal_have_nsa; +extern const unsigned char Xthal_have_minmax; +extern const unsigned char Xthal_have_sext; +extern const unsigned char Xthal_have_clamps; +extern const unsigned char Xthal_have_mac16; +extern const unsigned char Xthal_have_mul16; +extern const unsigned char Xthal_have_fp; +extern const unsigned char Xthal_have_speculation; +extern const unsigned char Xthal_have_threadptr; + +extern const unsigned char Xthal_have_pif; +extern const unsigned short Xthal_num_writebuffer_entries; + +extern const unsigned int Xthal_build_unique_id; +/* Version info for hardware targeted by software upgrades: */ +extern const unsigned int Xthal_hw_configid0; +extern const unsigned int Xthal_hw_configid1; +extern const unsigned int Xthal_hw_release_major; +extern const unsigned int Xthal_hw_release_minor; +extern const char * const Xthal_hw_release_name; +extern const char * const Xthal_hw_release_internal; + +#ifdef __cplusplus +} +#endif +#endif /*!_ASMLANGUAGE && !_NOCLANGUAGE && !__ASSEMBLER__ */ + + + + + +/**************************************************************************** + Definitions Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code + ****************************************************************************/ + + +#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY + +/*---------------------------------------------------------------------- + Constant Definitions (shared with assembly) + ----------------------------------------------------------------------*/ + +/* + * Architectural limits, independent of configuration. + * Note that these are ISA-defined limits, not micro-architecture implementation + * limits enforced by the Xtensa Processor Generator (which may be stricter than + * these below). + */ +#define XTHAL_MAX_INTERRUPTS 32 /* max number of interrupts (0..31) */ +#define XTHAL_MAX_INTLEVELS 16 /* max number of interrupt levels (0..15) */ + /* (as of T1040, implementation limit is 7: 0..6) */ +#define XTHAL_MAX_TIMERS 4 /* max number of timers (CCOMPARE0..CCOMPARE3) */ + /* (as of T1040, implementation limit is 3: 0..2) */ + +/* Interrupt types: */ +#define XTHAL_INTTYPE_UNCONFIGURED 0 +#define XTHAL_INTTYPE_SOFTWARE 1 +#define XTHAL_INTTYPE_EXTERN_EDGE 2 +#define XTHAL_INTTYPE_EXTERN_LEVEL 3 +#define XTHAL_INTTYPE_TIMER 4 +#define XTHAL_INTTYPE_NMI 5 +#define XTHAL_INTTYPE_WRITE_ERROR 6 +#define XTHAL_MAX_INTTYPES 7 /* number of interrupt types */ + +/* Timer related: */ +#define XTHAL_TIMER_UNCONFIGURED -1 /* Xthal_timer_interrupt[] value for non-existent timers */ +#define XTHAL_TIMER_UNASSIGNED XTHAL_TIMER_UNCONFIGURED /* (for backwards compatibility only) */ + +/* Local Memory ECC/Parity: */ +#define XTHAL_MEMEP_PARITY 1 +#define XTHAL_MEMEP_ECC 2 +/* Flags parameter to xthal_memep_inject_error(): */ +#define XTHAL_MEMEP_F_LOCAL 0 /* local memory (default) */ +#define XTHAL_MEMEP_F_DCACHE_DATA 4 /* data cache data */ +#define XTHAL_MEMEP_F_DCACHE_TAG 5 /* data cache tag */ +#define XTHAL_MEMEP_F_ICACHE_DATA 6 /* instruction cache data */ +#define XTHAL_MEMEP_F_ICACHE_TAG 7 /* instruction cache tag */ +#define XTHAL_MEMEP_F_CORRECTABLE 16 /* inject correctable error + (default is non-corr.) */ + + +/* Access Mode bits (tentative): */ /* bit abbr unit short_name PPC equ - Description */ +#define XTHAL_AMB_EXCEPTION 0 /* 001 E EX fls: EXception none + exception on any access (aka "illegal") */ +#define XTHAL_AMB_HITCACHE 1 /* 002 C CH fls: use Cache on Hit ~(I CI) + [or H HC] way from tag match; + [or U UC] (ISA: same except Isolate case) */ +#define XTHAL_AMB_ALLOCATE 2 /* 004 A AL fl?: ALlocate none + [or F FI fill] refill cache on miss, way from LRU + (ISA: Read/Write Miss Refill) */ +#define XTHAL_AMB_WRITETHRU 3 /* 008 W WT --s: WriteThrough W WT + store immediately to memory (ISA: same) */ +#define XTHAL_AMB_ISOLATE 4 /* 010 I IS fls: ISolate none + use cache regardless of hit-vs-miss, + way from vaddr (ISA: use-cache-on-miss+hit) */ +#define XTHAL_AMB_GUARD 5 /* 020 G GU ?l?: GUard G * + non-speculative; spec/replay refs not permitted */ +#define XTHAL_AMB_COHERENT 6 /* 040 M MC ?ls: Mem/MP Coherent M + on read, other CPU/bus-master may need to supply data; + on write, maybe redirect to or flush other CPU dirty line; etc */ +#if 0 +#define XTHAL_AMB_ORDERED x /* 000 O OR fls: ORdered G * + mem accesses cannot be out of order */ +#define XTHAL_AMB_FUSEWRITES x /* 000 F FW --s: FuseWrites none + allow combining/merging/coalescing multiple writes + (to same datapath data unit) into one + (implied by writeback) */ +#define XTHAL_AMB_TRUSTED x /* 000 T TR ?l?: TRusted none + memory will not bus error (if it does, + handle as fatal imprecise interrupt) */ +#define XTHAL_AMB_PREFETCH x /* 000 P PR fl?: PRefetch none + on refill, read line+1 into prefetch buffers */ +#define XTHAL_AMB_STREAM x /* 000 S ST ???: STreaming none + access one of N stream buffers */ +#endif /*0*/ + +#define XTHAL_AM_EXCEPTION (1< = bit is set + * '-' = bit is clear + * '.' = bit is irrelevant / don't care, as follows: + * E=1 makes all others irrelevant + * W,F relevant only for stores + * "2345" + * Indicates which Xtensa releases support the corresponding + * access mode. Releases for each character column are: + * 2 = prior to T1020.2: T1015 (V1.5), T1020.0, T1020.1 + * 3 = T1020.2 and later: T1020.2+, T1030 + * 4 = T1040 + * 5 = T1050 (maybe), LX1, LX2, LX2.1 + * 7 = LX2.2 + * 8 = LX3.0 + * And the character column contents are: + * = supported by release(s) + * "." = unsupported by release(s) + * "?" = support unknown + */ + /* FOMGIWACE 234578 */ +/* For instruction fetch: */ +#define XTHAL_FAM_EXCEPTION 0x001 /* ........E 234578 exception */ +/*efine XTHAL_FAM_ISOLATE*/ /*0x012*/ /* .---I.-C- ...... isolate */ +#define XTHAL_FAM_BYPASS 0x000 /* .----.--- 234578 bypass */ +/*efine XTHAL_FAM_NACACHED*/ /*0x002*/ /* .----.-C- ...... cached no-allocate (frozen) */ +#define XTHAL_FAM_CACHED 0x006 /* .----.AC- 234578 cached */ +/* For data load: */ +#define XTHAL_LAM_EXCEPTION 0x001 /* ........E 234578 exception */ +#define XTHAL_LAM_ISOLATE 0x012 /* .---I.-C- 234578 isolate */ +#define XTHAL_LAM_BYPASS 0x000 /* .O---.--- 2..... bypass speculative */ +#define XTHAL_LAM_BYPASSG 0x020 /* .O-G-.--- .34578 bypass guarded */ +#define XTHAL_LAM_CACHED_NOALLOC 0x002 /* .O---.-C- 234578 cached no-allocate speculative */ +#define XTHAL_LAM_NACACHED XTHAL_LAM_CACHED_NOALLOC +#define XTHAL_LAM_NACACHEDG 0x022 /* .O-G-.-C- .?.... cached no-allocate guarded */ +#define XTHAL_LAM_CACHED 0x006 /* .----.AC- 234578 cached speculative */ +#define XTHAL_LAM_COHCACHED 0x046 /* .-M--.AC- ....*8 cached speculative MP-coherent */ +/* For data store: */ +#define XTHAL_SAM_EXCEPTION 0x001 /* ........E 234578 exception */ +#define XTHAL_SAM_ISOLATE 0x032 /* .--GI--C- 234578 isolate */ +#define XTHAL_SAM_BYPASS 0x028 /* -O-G-W--- 234578 bypass */ +#define XTHAL_SAM_WRITETHRU 0x02A /* -O-G-W-C- 234578 writethrough */ +/*efine XTHAL_SAM_WRITETHRU_ALLOC*/ /*0x02E*/ /* -O-G-WAC- ...... writethrough allocate */ +#define XTHAL_SAM_WRITEBACK 0x026 /* F-MG--AC- ...578 writeback */ +#define XTHAL_SAM_COHWRITEBACK 0x066 /* F-MG--AC- ....*8 writeback MP-coherent */ +#define XTHAL_SAM_WRITEBACK_NOALLOC 0x022 /* ?--G---C- .....8 writeback no-allocate */ + +#if 0 +/* + Cache attribute encoding for CACHEATTR (per ISA): + (Note: if this differs from ISA Ref Manual, ISA has precedence) + + Inst-fetches Loads Stores + ------------- ------------ ------------- +0x0 FCA_EXCEPTION LCA_NACACHED SCA_WRITETHRU cached no-allocate (previously misnamed "uncached") +0x1 FCA_CACHED LCA_CACHED SCA_WRITETHRU cached +0x2 FCA_BYPASS LCA_BYPASS_G* SCA_BYPASS bypass cache (what most people call uncached) +0x3 FCA_CACHED LCA_CACHED SCA_WRITEALLOCF write-allocate + or LCA_EXCEPTION SCA_EXCEPTION (if unimplemented) +0x4 FCA_CACHED LCA_CACHED SCA_WRITEBACK[M] write-back [MP-coherent] + or LCA_EXCEPTION SCA_EXCEPTION (if unimplemented) +0x5 FCA_CACHED LCA_CACHED SCA_WRITEBACK_NOALLOC write-back no-allocate + or FCA_EXCEPTION LCA_EXCEPTION SCA_EXCEPTION (if unimplemented) +0x6..D FCA_EXCEPTION LCA_EXCEPTION SCA_EXCEPTION (reserved) +0xE FCA_EXCEPTION LCA_ISOLATE SCA_ISOLATE isolate +0xF FCA_EXCEPTION LCA_EXCEPTION SCA_EXCEPTION illegal + * Prior to T1020.2?, guard feature not supported, this defaulted to speculative (no _G) +*/ +#endif /*0*/ + + +#if !defined(_ASMLANGUAGE) && !defined(_NOCLANGUAGE) && !defined(__ASSEMBLER__) +#ifdef __cplusplus +extern "C" { +#endif + + +/*---------------------------------------------------------------------- + Register Windows + ----------------------------------------------------------------------*/ + +/* This spill any live register windows (other than the caller's): + * (NOTE: current implementation require privileged code, but + * a user-callable implementation is possible.) */ +extern void xthal_window_spill( void ); + + +/*---------------------------------------------------------------------- + Optional/Custom Processor State + ----------------------------------------------------------------------*/ + +/* validate & invalidate the TIE register file */ +extern void xthal_validate_cp(int); +extern void xthal_invalidate_cp(int); + +/* read and write cpenable register */ +extern void xthal_set_cpenable(unsigned); +extern unsigned xthal_get_cpenable(void); + + +/*---------------------------------------------------------------------- + Interrupts + ----------------------------------------------------------------------*/ + +/* the number of interrupt levels */ +extern const unsigned char Xthal_num_intlevels; +/* the number of interrupts */ +extern const unsigned char Xthal_num_interrupts; + +/* mask for level of interrupts */ +extern const unsigned int Xthal_intlevel_mask[XTHAL_MAX_INTLEVELS]; +/* mask for level 0 to N interrupts */ +extern const unsigned int Xthal_intlevel_andbelow_mask[XTHAL_MAX_INTLEVELS]; + +/* level of each interrupt */ +extern const unsigned char Xthal_intlevel[XTHAL_MAX_INTERRUPTS]; + +/* type per interrupt */ +extern const unsigned char Xthal_inttype[XTHAL_MAX_INTERRUPTS]; + +/* masks of each type of interrupt */ +extern const unsigned int Xthal_inttype_mask[XTHAL_MAX_INTTYPES]; + +/* interrupt numbers assigned to each timer interrupt */ +extern const int Xthal_timer_interrupt[XTHAL_MAX_TIMERS]; + +/* INTENABLE,INTERRUPT,INTSET,INTCLEAR register access functions: */ +extern unsigned xthal_get_intenable( void ); +extern void xthal_set_intenable( unsigned ); +extern unsigned xthal_get_interrupt( void ); +#define xthal_get_intread xthal_get_interrupt /* backward compatibility */ +extern void xthal_set_intset( unsigned ); +extern void xthal_set_intclear( unsigned ); + + +/*---------------------------------------------------------------------- + Debug + ----------------------------------------------------------------------*/ + +/* Number of instruction and data break registers: */ +extern const int Xthal_num_ibreak; +extern const int Xthal_num_dbreak; + + +/*---------------------------------------------------------------------- + Core Counter + ----------------------------------------------------------------------*/ + +/* counter info */ +extern const unsigned char Xthal_have_ccount; /* set if CCOUNT register present */ +extern const unsigned char Xthal_num_ccompare; /* number of CCOMPAREn registers */ + +/* get CCOUNT register (if not present return 0) */ +extern unsigned xthal_get_ccount(void); + +/* set and get CCOMPAREn registers (if not present, get returns 0) */ +extern void xthal_set_ccompare(int, unsigned); +extern unsigned xthal_get_ccompare(int); + + +/*---------------------------------------------------------------------- + Miscellaneous + ----------------------------------------------------------------------*/ + +extern const unsigned char Xthal_have_prid; +extern const unsigned char Xthal_have_exceptions; +extern const unsigned char Xthal_xea_version; +extern const unsigned char Xthal_have_interrupts; +extern const unsigned char Xthal_have_highlevel_interrupts; +extern const unsigned char Xthal_have_nmi; + +extern unsigned xthal_get_prid( void ); + + +/*---------------------------------------------------------------------- + Virtual interrupt prioritization (DEPRECATED) + ----------------------------------------------------------------------*/ + +/* Convert between interrupt levels (as per PS.INTLEVEL) and virtual interrupt priorities: */ +extern unsigned xthal_vpri_to_intlevel(unsigned vpri); +extern unsigned xthal_intlevel_to_vpri(unsigned intlevel); + +/* Enables/disables given set (mask) of interrupts; returns previous enabled-mask of all ints: */ +extern unsigned xthal_int_enable(unsigned); +extern unsigned xthal_int_disable(unsigned); + +/* Set/get virtual priority of an interrupt: */ +extern int xthal_set_int_vpri(int intnum, int vpri); +extern int xthal_get_int_vpri(int intnum); + +/* Set/get interrupt lockout level for exclusive access to virtual priority data structures: */ +extern void xthal_set_vpri_locklevel(unsigned intlevel); +extern unsigned xthal_get_vpri_locklevel(void); + +/* Set/get current virtual interrupt priority: */ +extern unsigned xthal_set_vpri(unsigned vpri); +extern unsigned xthal_get_vpri(void); +extern unsigned xthal_set_vpri_intlevel(unsigned intlevel); +extern unsigned xthal_set_vpri_lock(void); + + +/*---------------------------------------------------------------------- + Generic Interrupt Trampolining Support (DEPRECATED) + ----------------------------------------------------------------------*/ + +typedef void (XtHalVoidFunc)(void); + +/* Bitmask of interrupts currently trampolining down: */ +extern unsigned Xthal_tram_pending; + +/* + * Bitmask of which interrupts currently trampolining down synchronously are + * actually enabled; this bitmask is necessary because INTENABLE cannot hold + * that state (sync-trampolining interrupts must be kept disabled while + * trampolining); in the current implementation, any bit set here is not set + * in INTENABLE, and vice-versa; once a sync-trampoline is handled (at level + * one), its enable bit must be moved from here to INTENABLE: + */ +extern unsigned Xthal_tram_enabled; + +/* Bitmask of interrupts configured for sync trampolining: */ +extern unsigned Xthal_tram_sync; + +/* Trampoline support functions: */ +extern unsigned xthal_tram_pending_to_service( void ); +extern void xthal_tram_done( unsigned serviced_mask ); +extern int xthal_tram_set_sync( int intnum, int sync ); +extern XtHalVoidFunc* xthal_set_tram_trigger_func( XtHalVoidFunc *trigger_fn ); + + +/*---------------------------------------------------------------------- + Internal Memories + ----------------------------------------------------------------------*/ + +extern const unsigned char Xthal_num_instrom; +extern const unsigned char Xthal_num_instram; +extern const unsigned char Xthal_num_datarom; +extern const unsigned char Xthal_num_dataram; +extern const unsigned char Xthal_num_xlmi; + +/* Each of the following arrays contains at least one entry, + * or as many entries as needed if more than one: */ +extern const unsigned int Xthal_instrom_vaddr[]; +extern const unsigned int Xthal_instrom_paddr[]; +extern const unsigned int Xthal_instrom_size []; +extern const unsigned int Xthal_instram_vaddr[]; +extern const unsigned int Xthal_instram_paddr[]; +extern const unsigned int Xthal_instram_size []; +extern const unsigned int Xthal_datarom_vaddr[]; +extern const unsigned int Xthal_datarom_paddr[]; +extern const unsigned int Xthal_datarom_size []; +extern const unsigned int Xthal_dataram_vaddr[]; +extern const unsigned int Xthal_dataram_paddr[]; +extern const unsigned int Xthal_dataram_size []; +extern const unsigned int Xthal_xlmi_vaddr[]; +extern const unsigned int Xthal_xlmi_paddr[]; +extern const unsigned int Xthal_xlmi_size []; + + +/*---------------------------------------------------------------------- + Cache + ----------------------------------------------------------------------*/ + +/* number of cache sets in log2(lines per way) */ +extern const unsigned char Xthal_icache_setwidth; +extern const unsigned char Xthal_dcache_setwidth; +/* cache set associativity (number of ways) */ +extern const unsigned int Xthal_icache_ways; +extern const unsigned int Xthal_dcache_ways; +/* cache features */ +extern const unsigned char Xthal_icache_line_lockable; +extern const unsigned char Xthal_dcache_line_lockable; + +/* cache attribute register control (used by other HAL routines) */ +extern unsigned xthal_get_cacheattr( void ); +extern unsigned xthal_get_icacheattr( void ); +extern unsigned xthal_get_dcacheattr( void ); +extern void xthal_set_cacheattr( unsigned ); +extern void xthal_set_icacheattr( unsigned ); +extern void xthal_set_dcacheattr( unsigned ); +/* set cache attribute (access modes) for a range of memory */ +extern int xthal_set_region_attribute( void *addr, unsigned size, + unsigned cattr, unsigned flags ); +/* Bits of flags parameter to xthal_set_region_attribute(): */ +#define XTHAL_CAFLAG_EXPAND 0x000100 /* only expand allowed access to range, don't reduce it */ +#define XTHAL_CAFLAG_EXACT 0x000200 /* return error if can't apply change to exact range specified */ +#define XTHAL_CAFLAG_NO_PARTIAL 0x000400 /* don't apply change to regions partially covered by range */ +#define XTHAL_CAFLAG_NO_AUTO_WB 0x000800 /* don't writeback data after leaving writeback attribute */ +#define XTHAL_CAFLAG_NO_AUTO_INV 0x001000 /* don't invalidate after disabling cache (entering bypass) */ + +/* enable caches */ +extern void xthal_icache_enable( void ); /* DEPRECATED */ +extern void xthal_dcache_enable( void ); /* DEPRECATED */ +/* disable caches */ +extern void xthal_icache_disable( void ); /* DEPRECATED */ +extern void xthal_dcache_disable( void ); /* DEPRECATED */ + +/* invalidate the caches */ +extern void xthal_icache_all_invalidate( void ); +extern void xthal_dcache_all_invalidate( void ); +/* write dirty data back */ +extern void xthal_dcache_all_writeback( void ); +/* write dirty data back and invalidate */ +extern void xthal_dcache_all_writeback_inv( void ); +/* prefetch and lock specified memory range into cache */ +extern void xthal_icache_region_lock( void *addr, unsigned size ); +extern void xthal_dcache_region_lock( void *addr, unsigned size ); +extern void xthal_icache_line_lock(void *addr); +extern void xthal_dcache_line_lock(void *addr); +/* unlock from cache */ +extern void xthal_icache_all_unlock( void ); +extern void xthal_dcache_all_unlock( void ); +extern void xthal_icache_region_unlock( void *addr, unsigned size ); +extern void xthal_dcache_region_unlock( void *addr, unsigned size ); +extern void xthal_icache_line_unlock(void *addr); +extern void xthal_dcache_line_unlock(void *addr); + + + +/*---------------------------------------------------------------------- + Local Memory ECC/Parity + ----------------------------------------------------------------------*/ + +/* Inject memory errors; flags is bit combination of XTHAL_MEMEP_F_xxx: */ +extern void xthal_memep_inject_error(void *addr, int size, int flags); + + + +/*---------------------------------------------------------------------- + Memory Management Unit + ----------------------------------------------------------------------*/ + +extern const unsigned char Xthal_have_spanning_way; +extern const unsigned char Xthal_have_identity_map; +extern const unsigned char Xthal_have_mimic_cacheattr; +extern const unsigned char Xthal_have_xlt_cacheattr; +extern const unsigned char Xthal_have_cacheattr; +extern const unsigned char Xthal_have_tlbs; + +extern const unsigned char Xthal_mmu_asid_bits; /* 0 .. 8 */ +extern const unsigned char Xthal_mmu_asid_kernel; +extern const unsigned char Xthal_mmu_rings; /* 1 .. 4 (perhaps 0 if no MMU and/or no protection?) */ +extern const unsigned char Xthal_mmu_ring_bits; +extern const unsigned char Xthal_mmu_sr_bits; +extern const unsigned char Xthal_mmu_ca_bits; +extern const unsigned int Xthal_mmu_max_pte_page_size; +extern const unsigned int Xthal_mmu_min_pte_page_size; + +extern const unsigned char Xthal_itlb_way_bits; +extern const unsigned char Xthal_itlb_ways; +extern const unsigned char Xthal_itlb_arf_ways; +extern const unsigned char Xthal_dtlb_way_bits; +extern const unsigned char Xthal_dtlb_ways; +extern const unsigned char Xthal_dtlb_arf_ways; + +/* Convert between virtual and physical addresses (through static maps only): */ +/*** WARNING: these two functions may go away in a future release; don't depend on them! ***/ +extern int xthal_static_v2p( unsigned vaddr, unsigned *paddrp ); +extern int xthal_static_p2v( unsigned paddr, unsigned *vaddrp, unsigned cached ); + + +#ifdef __cplusplus +} +#endif +#endif /*!_ASMLANGUAGE && !_NOCLANGUAGE && !__ASSEMBLER__ */ + +#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ + + + + +/**************************************************************************** + EXPERIMENTAL and DEPRECATED Definitions + ****************************************************************************/ + + +#if !defined(_ASMLANGUAGE) && !defined(_NOCLANGUAGE) && !defined(__ASSEMBLER__) +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef INCLUDE_DEPRECATED_HAL_CODE +extern const unsigned char Xthal_have_old_exc_arch; +extern const unsigned char Xthal_have_mmu; +extern const unsigned int Xthal_num_regs; +extern const unsigned char Xthal_num_iroms; +extern const unsigned char Xthal_num_irams; +extern const unsigned char Xthal_num_droms; +extern const unsigned char Xthal_num_drams; +extern const unsigned int Xthal_configid0; +extern const unsigned int Xthal_configid1; +#endif + +#ifdef INCLUDE_DEPRECATED_HAL_DEBUG_CODE +#define XTHAL_24_BIT_BREAK 0x80000000 +#define XTHAL_16_BIT_BREAK 0x40000000 +extern const unsigned short Xthal_ill_inst_16[16]; +#define XTHAL_DEST_REG 0xf0000000 /* Mask for destination register */ +#define XTHAL_DEST_REG_INST 0x08000000 /* Branch address is in register */ +#define XTHAL_DEST_REL_INST 0x04000000 /* Branch address is relative */ +#define XTHAL_RFW_INST 0x00000800 +#define XTHAL_RFUE_INST 0x00000400 +#define XTHAL_RFI_INST 0x00000200 +#define XTHAL_RFE_INST 0x00000100 +#define XTHAL_RET_INST 0x00000080 +#define XTHAL_BREAK_INST 0x00000040 +#define XTHAL_SYSCALL_INST 0x00000020 +#define XTHAL_LOOP_END 0x00000010 /* Not set by xthal_inst_type */ +#define XTHAL_JUMP_INST 0x00000008 /* Call or jump instruction */ +#define XTHAL_BRANCH_INST 0x00000004 /* Branch instruction */ +#define XTHAL_24_BIT_INST 0x00000002 +#define XTHAL_16_BIT_INST 0x00000001 +typedef struct xthal_state { + unsigned pc; + unsigned ar[16]; + unsigned lbeg; + unsigned lend; + unsigned lcount; + unsigned extra_ptr; + unsigned cpregs_ptr[XTHAL_MAX_CPS]; +} XTHAL_STATE; +extern unsigned int xthal_inst_type(void *addr); +extern unsigned int xthal_branch_addr(void *addr); +extern unsigned int xthal_get_npc(XTHAL_STATE *user_state); +#endif /* INCLUDE_DEPRECATED_HAL_DEBUG_CODE */ + +#ifdef __cplusplus +} +#endif +#endif /*!_ASMLANGUAGE && !_NOCLANGUAGE && !__ASSEMBLER__ */ + +#endif /*XTENSA_HAL_H*/ + diff --git a/extra_include/xtensa/sim.h b/extra_include/xtensa/sim.h index 53d810b9..e02087c5 100644 --- a/extra_include/xtensa/sim.h +++ b/extra_include/xtensa/sim.h @@ -1,60 +1,60 @@ -/* Copyright (c) 2004-2006 by Tensilica Inc. ALL RIGHTS RESERVED. -/ These coded instructions, statements, and computer programs are the -/ copyrighted works and confidential proprietary information of Tensilica Inc. -/ They may not be modified, copied, reproduced, distributed, or disclosed to -/ third parties in any manner, medium, or form, in whole or in part, without -/ the prior written consent of Tensilica Inc. -*/ - -/* sim.h - * - * Definitions and prototypes for specific ISS SIMCALLs - * (ie. outside the standard C library). - */ - -#ifndef _INC_SIM_H_ -#define _INC_SIM_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Shortcuts for enabling/disabling profiling in the Xtensa ISS */ -extern void xt_iss_profile_enable(void); -extern void xt_iss_profile_disable(void); - -/* Shortcut for setting the trace level in the Xtensa ISS */ -extern void xt_iss_trace_level(unsigned level); - -/* Generic interface for passing client commands in the Xtensa ISS: - * returns 0 on success, -1 on failure. - */ -extern int xt_iss_client_command(const char *client, const char *command); - -/* Interface for switching simulation modes in the Xtensa ISS: - * returns 0 on success, -1 on failure. - */ -#define XT_ISS_CYCLE_ACCURATE 0 -#define XT_ISS_FUNCTIONAL 1 -extern int xt_iss_switch_mode(int mode); - - -/* Interface for waiting on a system synchronization event */ -extern void xt_iss_event_wait(unsigned event_id); - -/* Interface for firing a system synchronization event */ -extern void xt_iss_event_fire(unsigned event_id); - -/* Interface for invoking a user simcall action, - * which can be registered in XTMP or XTSC. - */ -extern int xt_iss_simcall(int arg1, int arg2, int arg3, - int arg4, int arg5, int arg6); - - -#ifdef __cplusplus -} -#endif - -#endif /*_INC_SIM_H_*/ - +/* Copyright (c) 2004-2006 by Tensilica Inc. ALL RIGHTS RESERVED. +/ These coded instructions, statements, and computer programs are the +/ copyrighted works and confidential proprietary information of Tensilica Inc. +/ They may not be modified, copied, reproduced, distributed, or disclosed to +/ third parties in any manner, medium, or form, in whole or in part, without +/ the prior written consent of Tensilica Inc. +*/ + +/* sim.h + * + * Definitions and prototypes for specific ISS SIMCALLs + * (ie. outside the standard C library). + */ + +#ifndef _INC_SIM_H_ +#define _INC_SIM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Shortcuts for enabling/disabling profiling in the Xtensa ISS */ +extern void xt_iss_profile_enable(void); +extern void xt_iss_profile_disable(void); + +/* Shortcut for setting the trace level in the Xtensa ISS */ +extern void xt_iss_trace_level(unsigned level); + +/* Generic interface for passing client commands in the Xtensa ISS: + * returns 0 on success, -1 on failure. + */ +extern int xt_iss_client_command(const char *client, const char *command); + +/* Interface for switching simulation modes in the Xtensa ISS: + * returns 0 on success, -1 on failure. + */ +#define XT_ISS_CYCLE_ACCURATE 0 +#define XT_ISS_FUNCTIONAL 1 +extern int xt_iss_switch_mode(int mode); + + +/* Interface for waiting on a system synchronization event */ +extern void xt_iss_event_wait(unsigned event_id); + +/* Interface for firing a system synchronization event */ +extern void xt_iss_event_fire(unsigned event_id); + +/* Interface for invoking a user simcall action, + * which can be registered in XTMP or XTSC. + */ +extern int xt_iss_simcall(int arg1, int arg2, int arg3, + int arg4, int arg5, int arg6); + + +#ifdef __cplusplus +} +#endif + +#endif /*_INC_SIM_H_*/ + diff --git a/extra_include/xtensa/simcall-errno.h b/extra_include/xtensa/simcall-errno.h index a6420129..445ec901 100644 --- a/extra_include/xtensa/simcall-errno.h +++ b/extra_include/xtensa/simcall-errno.h @@ -1,139 +1,139 @@ -/* Error numbers for Xtensa ISS semihosting. */ - -/* Copyright (c) 2003 by Tensilica Inc. ALL RIGHTS RESERVED. - These coded instructions, statements, and computer programs are the - copyrighted works and confidential proprietary information of Tensilica Inc. - They may not be modified, copied, reproduced, distributed, or disclosed to - third parties in any manner, medium, or form, in whole or in part, without - the prior written consent of Tensilica Inc. */ - -#ifndef _SIMCALL_ERRNO_H -#define _SIMCALL_ERRNO_H - -/* Define the error numbers (using the default newlib values) with prefixes - so they can be used in ISS without conflicting with the host values. */ - -#define _SIMC_EPERM 1 -#define _SIMC_ENOENT 2 -#define _SIMC_ESRCH 3 -#define _SIMC_EINTR 4 -#define _SIMC_EIO 5 -#define _SIMC_ENXIO 6 -#define _SIMC_E2BIG 7 -#define _SIMC_ENOEXEC 8 -#define _SIMC_EBADF 9 -#define _SIMC_ECHILD 10 -#define _SIMC_EAGAIN 11 -#define _SIMC_ENOMEM 12 -#define _SIMC_EACCES 13 -#define _SIMC_EFAULT 14 -#define _SIMC_ENOTBLK 15 -#define _SIMC_EBUSY 16 -#define _SIMC_EEXIST 17 -#define _SIMC_EXDEV 18 -#define _SIMC_ENODEV 19 -#define _SIMC_ENOTDIR 20 -#define _SIMC_EISDIR 21 -#define _SIMC_EINVAL 22 -#define _SIMC_ENFILE 23 -#define _SIMC_EMFILE 24 -#define _SIMC_ENOTTY 25 -#define _SIMC_ETXTBSY 26 -#define _SIMC_EFBIG 27 -#define _SIMC_ENOSPC 28 -#define _SIMC_ESPIPE 29 -#define _SIMC_EROFS 30 -#define _SIMC_EMLINK 31 -#define _SIMC_EPIPE 32 -#define _SIMC_EDOM 33 -#define _SIMC_ERANGE 34 -#define _SIMC_ENOMSG 35 -#define _SIMC_EIDRM 36 -#define _SIMC_ECHRNG 37 -#define _SIMC_EL2NSYNC 38 -#define _SIMC_EL3HLT 39 -#define _SIMC_EL3RST 40 -#define _SIMC_ELNRNG 41 -#define _SIMC_EUNATCH 42 -#define _SIMC_ENOCSI 43 -#define _SIMC_EL2HLT 44 -#define _SIMC_EDEADLK 45 -#define _SIMC_ENOLCK 46 -#define _SIMC_EBADE 50 -#define _SIMC_EBADR 51 -#define _SIMC_EXFULL 52 -#define _SIMC_ENOANO 53 -#define _SIMC_EBADRQC 54 -#define _SIMC_EBADSLT 55 -#define _SIMC_EDEADLOCK 56 -#define _SIMC_EBFONT 57 -#define _SIMC_ENOSTR 60 -#define _SIMC_ENODATA 61 -#define _SIMC_ETIME 62 -#define _SIMC_ENOSR 63 -#define _SIMC_ENONET 64 -#define _SIMC_ENOPKG 65 -#define _SIMC_EREMOTE 66 -#define _SIMC_ENOLINK 67 -#define _SIMC_EADV 68 -#define _SIMC_ESRMNT 69 -#define _SIMC_ECOMM 70 -#define _SIMC_EPROTO 71 -#define _SIMC_EMULTIHOP 74 -#define _SIMC_ELBIN 75 -#define _SIMC_EDOTDOT 76 -#define _SIMC_EBADMSG 77 -#define _SIMC_EFTYPE 79 -#define _SIMC_ENOTUNIQ 80 -#define _SIMC_EBADFD 81 -#define _SIMC_EREMCHG 82 -#define _SIMC_ELIBACC 83 -#define _SIMC_ELIBBAD 84 -#define _SIMC_ELIBSCN 85 -#define _SIMC_ELIBMAX 86 -#define _SIMC_ELIBEXEC 87 -#define _SIMC_ENOSYS 88 -#define _SIMC_ENMFILE 89 -#define _SIMC_ENOTEMPTY 90 -#define _SIMC_ENAMETOOLONG 91 -#define _SIMC_ELOOP 92 -#define _SIMC_EOPNOTSUPP 95 -#define _SIMC_EPFNOSUPPORT 96 -#define _SIMC_ECONNRESET 104 -#define _SIMC_ENOBUFS 105 -#define _SIMC_EAFNOSUPPORT 106 -#define _SIMC_EPROTOTYPE 107 -#define _SIMC_ENOTSOCK 108 -#define _SIMC_ENOPROTOOPT 109 -#define _SIMC_ESHUTDOWN 110 -#define _SIMC_ECONNREFUSED 111 -#define _SIMC_EADDRINUSE 112 -#define _SIMC_ECONNABORTED 113 -#define _SIMC_ENETUNREACH 114 -#define _SIMC_ENETDOWN 115 -#define _SIMC_ETIMEDOUT 116 -#define _SIMC_EHOSTDOWN 117 -#define _SIMC_EHOSTUNREACH 118 -#define _SIMC_EINPROGRESS 119 -#define _SIMC_EALREADY 120 -#define _SIMC_EDESTADDRREQ 121 -#define _SIMC_EMSGSIZE 122 -#define _SIMC_EPROTONOSUPPORT 123 -#define _SIMC_ESOCKTNOSUPPORT 124 -#define _SIMC_EADDRNOTAVAIL 125 -#define _SIMC_ENETRESET 126 -#define _SIMC_EISCONN 127 -#define _SIMC_ENOTCONN 128 -#define _SIMC_ETOOMANYREFS 129 -#define _SIMC_EPROCLIM 130 -#define _SIMC_EUSERS 131 -#define _SIMC_EDQUOT 132 -#define _SIMC_ESTALE 133 -#define _SIMC_ENOTSUP 134 -#define _SIMC_ENOMEDIUM 135 -#define _SIMC_ENOSHARE 136 -#define _SIMC_ECASECLASH 137 -#define _SIMC_EILSEQ 138 -#define _SIMC_EOVERFLOW 139 - -#endif /* ! _SIMCALL_ERRNO_H */ +/* Error numbers for Xtensa ISS semihosting. */ + +/* Copyright (c) 2003 by Tensilica Inc. ALL RIGHTS RESERVED. + These coded instructions, statements, and computer programs are the + copyrighted works and confidential proprietary information of Tensilica Inc. + They may not be modified, copied, reproduced, distributed, or disclosed to + third parties in any manner, medium, or form, in whole or in part, without + the prior written consent of Tensilica Inc. */ + +#ifndef _SIMCALL_ERRNO_H +#define _SIMCALL_ERRNO_H + +/* Define the error numbers (using the default newlib values) with prefixes + so they can be used in ISS without conflicting with the host values. */ + +#define _SIMC_EPERM 1 +#define _SIMC_ENOENT 2 +#define _SIMC_ESRCH 3 +#define _SIMC_EINTR 4 +#define _SIMC_EIO 5 +#define _SIMC_ENXIO 6 +#define _SIMC_E2BIG 7 +#define _SIMC_ENOEXEC 8 +#define _SIMC_EBADF 9 +#define _SIMC_ECHILD 10 +#define _SIMC_EAGAIN 11 +#define _SIMC_ENOMEM 12 +#define _SIMC_EACCES 13 +#define _SIMC_EFAULT 14 +#define _SIMC_ENOTBLK 15 +#define _SIMC_EBUSY 16 +#define _SIMC_EEXIST 17 +#define _SIMC_EXDEV 18 +#define _SIMC_ENODEV 19 +#define _SIMC_ENOTDIR 20 +#define _SIMC_EISDIR 21 +#define _SIMC_EINVAL 22 +#define _SIMC_ENFILE 23 +#define _SIMC_EMFILE 24 +#define _SIMC_ENOTTY 25 +#define _SIMC_ETXTBSY 26 +#define _SIMC_EFBIG 27 +#define _SIMC_ENOSPC 28 +#define _SIMC_ESPIPE 29 +#define _SIMC_EROFS 30 +#define _SIMC_EMLINK 31 +#define _SIMC_EPIPE 32 +#define _SIMC_EDOM 33 +#define _SIMC_ERANGE 34 +#define _SIMC_ENOMSG 35 +#define _SIMC_EIDRM 36 +#define _SIMC_ECHRNG 37 +#define _SIMC_EL2NSYNC 38 +#define _SIMC_EL3HLT 39 +#define _SIMC_EL3RST 40 +#define _SIMC_ELNRNG 41 +#define _SIMC_EUNATCH 42 +#define _SIMC_ENOCSI 43 +#define _SIMC_EL2HLT 44 +#define _SIMC_EDEADLK 45 +#define _SIMC_ENOLCK 46 +#define _SIMC_EBADE 50 +#define _SIMC_EBADR 51 +#define _SIMC_EXFULL 52 +#define _SIMC_ENOANO 53 +#define _SIMC_EBADRQC 54 +#define _SIMC_EBADSLT 55 +#define _SIMC_EDEADLOCK 56 +#define _SIMC_EBFONT 57 +#define _SIMC_ENOSTR 60 +#define _SIMC_ENODATA 61 +#define _SIMC_ETIME 62 +#define _SIMC_ENOSR 63 +#define _SIMC_ENONET 64 +#define _SIMC_ENOPKG 65 +#define _SIMC_EREMOTE 66 +#define _SIMC_ENOLINK 67 +#define _SIMC_EADV 68 +#define _SIMC_ESRMNT 69 +#define _SIMC_ECOMM 70 +#define _SIMC_EPROTO 71 +#define _SIMC_EMULTIHOP 74 +#define _SIMC_ELBIN 75 +#define _SIMC_EDOTDOT 76 +#define _SIMC_EBADMSG 77 +#define _SIMC_EFTYPE 79 +#define _SIMC_ENOTUNIQ 80 +#define _SIMC_EBADFD 81 +#define _SIMC_EREMCHG 82 +#define _SIMC_ELIBACC 83 +#define _SIMC_ELIBBAD 84 +#define _SIMC_ELIBSCN 85 +#define _SIMC_ELIBMAX 86 +#define _SIMC_ELIBEXEC 87 +#define _SIMC_ENOSYS 88 +#define _SIMC_ENMFILE 89 +#define _SIMC_ENOTEMPTY 90 +#define _SIMC_ENAMETOOLONG 91 +#define _SIMC_ELOOP 92 +#define _SIMC_EOPNOTSUPP 95 +#define _SIMC_EPFNOSUPPORT 96 +#define _SIMC_ECONNRESET 104 +#define _SIMC_ENOBUFS 105 +#define _SIMC_EAFNOSUPPORT 106 +#define _SIMC_EPROTOTYPE 107 +#define _SIMC_ENOTSOCK 108 +#define _SIMC_ENOPROTOOPT 109 +#define _SIMC_ESHUTDOWN 110 +#define _SIMC_ECONNREFUSED 111 +#define _SIMC_EADDRINUSE 112 +#define _SIMC_ECONNABORTED 113 +#define _SIMC_ENETUNREACH 114 +#define _SIMC_ENETDOWN 115 +#define _SIMC_ETIMEDOUT 116 +#define _SIMC_EHOSTDOWN 117 +#define _SIMC_EHOSTUNREACH 118 +#define _SIMC_EINPROGRESS 119 +#define _SIMC_EALREADY 120 +#define _SIMC_EDESTADDRREQ 121 +#define _SIMC_EMSGSIZE 122 +#define _SIMC_EPROTONOSUPPORT 123 +#define _SIMC_ESOCKTNOSUPPORT 124 +#define _SIMC_EADDRNOTAVAIL 125 +#define _SIMC_ENETRESET 126 +#define _SIMC_EISCONN 127 +#define _SIMC_ENOTCONN 128 +#define _SIMC_ETOOMANYREFS 129 +#define _SIMC_EPROCLIM 130 +#define _SIMC_EUSERS 131 +#define _SIMC_EDQUOT 132 +#define _SIMC_ESTALE 133 +#define _SIMC_ENOTSUP 134 +#define _SIMC_ENOMEDIUM 135 +#define _SIMC_ENOSHARE 136 +#define _SIMC_ECASECLASH 137 +#define _SIMC_EILSEQ 138 +#define _SIMC_EOVERFLOW 139 + +#endif /* ! _SIMCALL_ERRNO_H */ diff --git a/extra_include/xtensa/simcall-fcntl.h b/extra_include/xtensa/simcall-fcntl.h index ce334660..1c03f559 100644 --- a/extra_include/xtensa/simcall-fcntl.h +++ b/extra_include/xtensa/simcall-fcntl.h @@ -1,21 +1,21 @@ -/* File control operations for Xtensa ISS semihosting. */ - -/* Copyright (c) 2003 by Tensilica Inc. ALL RIGHTS RESERVED. - These coded instructions, statements, and computer programs are the - copyrighted works and confidential proprietary information of Tensilica Inc. - They may not be modified, copied, reproduced, distributed, or disclosed to - third parties in any manner, medium, or form, in whole or in part, without - the prior written consent of Tensilica Inc. */ - -#ifndef _SIMCALL_FCNTL_H -#define _SIMCALL_FCNTL_H - -#define _SIMC_O_APPEND 0x0008 -#define _SIMC_O_NONBLOCK 0x0080 -#define _SIMC_O_CREAT 0x0100 -#define _SIMC_O_TRUNC 0x0200 -#define _SIMC_O_EXCL 0x0400 -#define _SIMC_O_TEXT 0x4000 -#define _SIMC_O_BINARY 0x8000 - -#endif /* ! _SIMCALL_FCNTL_H */ +/* File control operations for Xtensa ISS semihosting. */ + +/* Copyright (c) 2003 by Tensilica Inc. ALL RIGHTS RESERVED. + These coded instructions, statements, and computer programs are the + copyrighted works and confidential proprietary information of Tensilica Inc. + They may not be modified, copied, reproduced, distributed, or disclosed to + third parties in any manner, medium, or form, in whole or in part, without + the prior written consent of Tensilica Inc. */ + +#ifndef _SIMCALL_FCNTL_H +#define _SIMCALL_FCNTL_H + +#define _SIMC_O_APPEND 0x0008 +#define _SIMC_O_NONBLOCK 0x0080 +#define _SIMC_O_CREAT 0x0100 +#define _SIMC_O_TRUNC 0x0200 +#define _SIMC_O_EXCL 0x0400 +#define _SIMC_O_TEXT 0x4000 +#define _SIMC_O_BINARY 0x8000 + +#endif /* ! _SIMCALL_FCNTL_H */ diff --git a/extra_include/xtensa/simcall.h b/extra_include/xtensa/simcall.h index 96453702..91118d0b 100644 --- a/extra_include/xtensa/simcall.h +++ b/extra_include/xtensa/simcall.h @@ -1,188 +1,188 @@ -/* - * simcall.h - Simulator call numbers - * - * Software that runs on a simulated Xtensa processor using - * the instruction set simulator (ISS) can invoke simulator - * services using the SIMCALL instruction. The a2 register - * is set prior to executing SIMCALL to a "simcall number", - * indicating which service to invoke. This file defines the - * simcall numbers defined and/or supported by the Xtensa ISS. - * - * IMPORTANT NOTE: These numbers are highly subject to change! - * - * Copyright (c) 2002-2007 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -#ifndef SIMCALL_INCLUDED -#define SIMCALL_INCLUDED - -/* - * System call like services offered by the simulator host. - * These are modeled after the Linux 2.4 kernel system calls - * for Xtensa processors. However not all system calls and - * not all functionality of a given system call are implemented, - * or necessarily have well defined or equivalent semantics in - * the context of a simulation (as opposed to a Unix kernel). - * - * These services behave largely as if they had been invoked - * as a task in the simulator host's operating system - * (eg. files accessed are those of the simulator host). - * However, these SIMCALLs model a virtual operating system - * so that various definitions, bit assignments etc - * (eg. open mode bits, errno values, etc) are independent - * of the host operating system used to run the simulation. - * Rather these definitions are specific to the Xtensa ISS. - * This way Xtensa ISA code written to use these SIMCALLs - * can (in principle) be simulated on any host. - * - * Up to 6 parameters are passed in registers a3 to a8 - * (note the 6th parameter isn't passed on the stack, - * unlike windowed function calling conventions). - * The return value is in a2. A negative value in the - * range -4096 to -1 indicates a negated error code to be - * reported in errno with a return value of -1, otherwise - * the value in a2 is returned as is. - */ - -/* These #defines need to match what's in Xtensa/OS/vxworks/xtiss/simcalls.c */ - -#define SYS_nop 0 /* n/a - setup; used to flush register windows */ -#define SYS_exit 1 /*x*/ -#define SYS_fork 2 -#define SYS_read 3 /*x*/ -#define SYS_write 4 /*x*/ -#define SYS_open 5 /*x*/ -#define SYS_close 6 /*x*/ -#define SYS_rename 7 /*x 38 - waitpid */ -#define SYS_creat 8 /*x*/ -#define SYS_link 9 /*x (not implemented on WIN32) */ -#define SYS_unlink 10 /*x*/ -#define SYS_execv 11 /* n/a - execve */ -#define SYS_execve 12 /* 11 - chdir */ -#define SYS_pipe 13 /* 42 - time */ -#define SYS_stat 14 /* 106 - mknod */ -#define SYS_chmod 15 -#define SYS_chown 16 /* 202 - lchown */ -#define SYS_utime 17 /* 30 - break */ -#define SYS_wait 18 /* n/a - oldstat */ -#define SYS_lseek 19 /*x*/ -#define SYS_getpid 20 -#define SYS_isatty 21 /* n/a - mount */ -#define SYS_fstat 22 /* 108 - oldumount */ -#define SYS_time 23 /* 13 - setuid */ -#define SYS_gettimeofday 24 /*x 78 - getuid (not implemented on WIN32) */ -#define SYS_times 25 /*X 43 - stime (Xtensa-specific implementation) */ -#define SYS_socket 26 -#define SYS_sendto 27 -#define SYS_recvfrom 28 -#define SYS_select_one 29 /* not compitible select, one file descriptor at the time */ -#define SYS_bind 30 -#define SYS_ioctl 31 - -/* - * Other... - */ -#define SYS_iss_argc 1000 /* returns value of argc */ -#define SYS_iss_argv_size 1001 /* bytes needed for argv & arg strings */ -#define SYS_iss_set_argv 1002 /* saves argv & arg strings at given addr */ - -#define SYS_memset 1004 /* fill a range of memory (fast) */ - -/* - * SIMCALLs for the ferret memory debugger. All are invoked by - * libferret.a ... ( Xtensa/Target-Libs/ferret ) - */ -#define SYS_ferret 1010 -#define SYS_malloc 1011 -#define SYS_free 1012 -#define SYS_more_heap 1013 -#define SYS_no_heap 1014 -#define SYS_enter_ferret 1015 -#define SYS_leave_ferret 1016 - -/* - * SIMCALLs for ISS client commands - */ -#define SYS_profile_enable 1020 -#define SYS_profile_disable 1021 -#define SYS_trace_level 1022 -#define SYS_client_command 1023 - -/* - * SIMCALL for simulation mode switching - */ -#define SYS_sim_mode_switch 1030 - -/* - * SIMCALLs for XTMP/XTSC event notify and core stall - */ -#define SYS_event_fire 1040 -#define SYS_event_stall 1041 - -/* - * SIMCALLs for callbacks registered in XTMP/XTSC - */ -#define SYS_callback_first 100 -#define SYS_callback_last 999 - -/* - * User defined simcall - */ -#define SYS_user_simcall 100 - -#define SYS_xmpa_errinfo 200 -#define SYS_xmpa_proc_status 201 -#define SYS_xmpa_proc_start 202 -#define SYS_xmpa_proc_stop 203 -#define SYS_xmpa_proc_mem_read 204 -#define SYS_xmpa_proc_mem_write 205 -#define SYS_xmpa_proc_mem_fill 206 -#define SYS_xmpa_proc_reg_read 207 -#define SYS_xmpa_proc_reg_write 208 - - -/* - * Extra SIMCALLs for GDB: - */ -#define SYS_gdb_break -1 /* invoked by XTOS on user exceptions if EPC points - to a break.n/break, regardless of cause! */ -#define SYS_xmon_out -2 /* invoked by XMON: ... */ -#define SYS_xmon_in -3 /* invoked by XMON: ... */ -#define SYS_xmon_flush -4 /* invoked by XMON: ... */ -#define SYS_gdb_abort -5 /* invoked by XTOS in _xtos_panic() */ -#define SYS_gdb_illegal_inst -6 /* invoked by XTOS for illegal instructions (too deeply) */ -#define SYS_xmon_init -7 /* invoked by XMON: ... */ -#define SYS_gdb_enter_sktloop -8 /* invoked by XTOS on debug exceptions */ -#define SYS_unhandled_kernel_exc -9 /* invoked by XTOS for unhandled kernel exceptions */ -#define SYS_unhandled_user_exc -10 /* invoked by XTOS for unhandled user exceptions */ -#define SYS_unhandled_double_exc -11 /* invoked by XTOS for unhandled double exceptions */ -#define SYS_unhandled_highpri_interrupt -12 /* invoked by XTOS for unhandled high-priority interrupts */ - -/* - * SIMCALLs for vxWorks xtiss BSP: - */ -#define SYS_setup_ppp_pipes -83 -#define SYS_log_msg -84 - -/* - * SYS_select_one specifiers - */ -#define XTISS_SELECT_ONE_READ 1 -#define XTISS_SELECT_ONE_WRITE 2 -#define XTISS_SELECT_ONE_EXCEPT 3 - -/* - * SIMCALL for client calling arbitrary code in a client plug in. - * see clients/xcc_instr to see how this works. - */ - -#define SYS_client 0xC0DECAFE - - - -#endif /* !SIMCALL_INCLUDED */ +/* + * simcall.h - Simulator call numbers + * + * Software that runs on a simulated Xtensa processor using + * the instruction set simulator (ISS) can invoke simulator + * services using the SIMCALL instruction. The a2 register + * is set prior to executing SIMCALL to a "simcall number", + * indicating which service to invoke. This file defines the + * simcall numbers defined and/or supported by the Xtensa ISS. + * + * IMPORTANT NOTE: These numbers are highly subject to change! + * + * Copyright (c) 2002-2007 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +#ifndef SIMCALL_INCLUDED +#define SIMCALL_INCLUDED + +/* + * System call like services offered by the simulator host. + * These are modeled after the Linux 2.4 kernel system calls + * for Xtensa processors. However not all system calls and + * not all functionality of a given system call are implemented, + * or necessarily have well defined or equivalent semantics in + * the context of a simulation (as opposed to a Unix kernel). + * + * These services behave largely as if they had been invoked + * as a task in the simulator host's operating system + * (eg. files accessed are those of the simulator host). + * However, these SIMCALLs model a virtual operating system + * so that various definitions, bit assignments etc + * (eg. open mode bits, errno values, etc) are independent + * of the host operating system used to run the simulation. + * Rather these definitions are specific to the Xtensa ISS. + * This way Xtensa ISA code written to use these SIMCALLs + * can (in principle) be simulated on any host. + * + * Up to 6 parameters are passed in registers a3 to a8 + * (note the 6th parameter isn't passed on the stack, + * unlike windowed function calling conventions). + * The return value is in a2. A negative value in the + * range -4096 to -1 indicates a negated error code to be + * reported in errno with a return value of -1, otherwise + * the value in a2 is returned as is. + */ + +/* These #defines need to match what's in Xtensa/OS/vxworks/xtiss/simcalls.c */ + +#define SYS_nop 0 /* n/a - setup; used to flush register windows */ +#define SYS_exit 1 /*x*/ +#define SYS_fork 2 +#define SYS_read 3 /*x*/ +#define SYS_write 4 /*x*/ +#define SYS_open 5 /*x*/ +#define SYS_close 6 /*x*/ +#define SYS_rename 7 /*x 38 - waitpid */ +#define SYS_creat 8 /*x*/ +#define SYS_link 9 /*x (not implemented on WIN32) */ +#define SYS_unlink 10 /*x*/ +#define SYS_execv 11 /* n/a - execve */ +#define SYS_execve 12 /* 11 - chdir */ +#define SYS_pipe 13 /* 42 - time */ +#define SYS_stat 14 /* 106 - mknod */ +#define SYS_chmod 15 +#define SYS_chown 16 /* 202 - lchown */ +#define SYS_utime 17 /* 30 - break */ +#define SYS_wait 18 /* n/a - oldstat */ +#define SYS_lseek 19 /*x*/ +#define SYS_getpid 20 +#define SYS_isatty 21 /* n/a - mount */ +#define SYS_fstat 22 /* 108 - oldumount */ +#define SYS_time 23 /* 13 - setuid */ +#define SYS_gettimeofday 24 /*x 78 - getuid (not implemented on WIN32) */ +#define SYS_times 25 /*X 43 - stime (Xtensa-specific implementation) */ +#define SYS_socket 26 +#define SYS_sendto 27 +#define SYS_recvfrom 28 +#define SYS_select_one 29 /* not compitible select, one file descriptor at the time */ +#define SYS_bind 30 +#define SYS_ioctl 31 + +/* + * Other... + */ +#define SYS_iss_argc 1000 /* returns value of argc */ +#define SYS_iss_argv_size 1001 /* bytes needed for argv & arg strings */ +#define SYS_iss_set_argv 1002 /* saves argv & arg strings at given addr */ + +#define SYS_memset 1004 /* fill a range of memory (fast) */ + +/* + * SIMCALLs for the ferret memory debugger. All are invoked by + * libferret.a ... ( Xtensa/Target-Libs/ferret ) + */ +#define SYS_ferret 1010 +#define SYS_malloc 1011 +#define SYS_free 1012 +#define SYS_more_heap 1013 +#define SYS_no_heap 1014 +#define SYS_enter_ferret 1015 +#define SYS_leave_ferret 1016 + +/* + * SIMCALLs for ISS client commands + */ +#define SYS_profile_enable 1020 +#define SYS_profile_disable 1021 +#define SYS_trace_level 1022 +#define SYS_client_command 1023 + +/* + * SIMCALL for simulation mode switching + */ +#define SYS_sim_mode_switch 1030 + +/* + * SIMCALLs for XTMP/XTSC event notify and core stall + */ +#define SYS_event_fire 1040 +#define SYS_event_stall 1041 + +/* + * SIMCALLs for callbacks registered in XTMP/XTSC + */ +#define SYS_callback_first 100 +#define SYS_callback_last 999 + +/* + * User defined simcall + */ +#define SYS_user_simcall 100 + +#define SYS_xmpa_errinfo 200 +#define SYS_xmpa_proc_status 201 +#define SYS_xmpa_proc_start 202 +#define SYS_xmpa_proc_stop 203 +#define SYS_xmpa_proc_mem_read 204 +#define SYS_xmpa_proc_mem_write 205 +#define SYS_xmpa_proc_mem_fill 206 +#define SYS_xmpa_proc_reg_read 207 +#define SYS_xmpa_proc_reg_write 208 + + +/* + * Extra SIMCALLs for GDB: + */ +#define SYS_gdb_break -1 /* invoked by XTOS on user exceptions if EPC points + to a break.n/break, regardless of cause! */ +#define SYS_xmon_out -2 /* invoked by XMON: ... */ +#define SYS_xmon_in -3 /* invoked by XMON: ... */ +#define SYS_xmon_flush -4 /* invoked by XMON: ... */ +#define SYS_gdb_abort -5 /* invoked by XTOS in _xtos_panic() */ +#define SYS_gdb_illegal_inst -6 /* invoked by XTOS for illegal instructions (too deeply) */ +#define SYS_xmon_init -7 /* invoked by XMON: ... */ +#define SYS_gdb_enter_sktloop -8 /* invoked by XTOS on debug exceptions */ +#define SYS_unhandled_kernel_exc -9 /* invoked by XTOS for unhandled kernel exceptions */ +#define SYS_unhandled_user_exc -10 /* invoked by XTOS for unhandled user exceptions */ +#define SYS_unhandled_double_exc -11 /* invoked by XTOS for unhandled double exceptions */ +#define SYS_unhandled_highpri_interrupt -12 /* invoked by XTOS for unhandled high-priority interrupts */ + +/* + * SIMCALLs for vxWorks xtiss BSP: + */ +#define SYS_setup_ppp_pipes -83 +#define SYS_log_msg -84 + +/* + * SYS_select_one specifiers + */ +#define XTISS_SELECT_ONE_READ 1 +#define XTISS_SELECT_ONE_WRITE 2 +#define XTISS_SELECT_ONE_EXCEPT 3 + +/* + * SIMCALL for client calling arbitrary code in a client plug in. + * see clients/xcc_instr to see how this works. + */ + +#define SYS_client 0xC0DECAFE + + + +#endif /* !SIMCALL_INCLUDED */ diff --git a/extra_include/xtensa/specreg.h b/extra_include/xtensa/specreg.h index 8df479c5..4c4f9171 100644 --- a/extra_include/xtensa/specreg.h +++ b/extra_include/xtensa/specreg.h @@ -1,138 +1,138 @@ -/* - * Xtensa Special Register symbolic names - */ - -/* $Id: //depot/rel/Boreal/Xtensa/OS/include/xtensa/specreg.h#2 $ */ - -/* - * Copyright (c) 2005-2010 Tensilica Inc. - * - * 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 XTENSA_SPECREG_H -#define XTENSA_SPECREG_H - -/* Special registers: */ -#define LBEG 0 -#define LEND 1 -#define LCOUNT 2 -#define SAR 3 -#define BR 4 -#define LITBASE 5 -#define SCOMPARE1 12 -#define ACCLO 16 -#define ACCHI 17 -#define MR_0 32 -#define MR_1 33 -#define MR_2 34 -#define MR_3 35 -#define PREFCTL 40 -#define WINDOWBASE 72 -#define WINDOWSTART 73 -#define PTEVADDR 83 -#define RASID 90 -#define ITLBCFG 91 -#define DTLBCFG 92 -#define IBREAKENABLE 96 -#define CACHEATTR 98 -#define DDR 104 -#define IBREAKA_0 128 -#define IBREAKA_1 129 -#define DBREAKA_0 144 -#define DBREAKA_1 145 -#define DBREAKC_0 160 -#define DBREAKC_1 161 -#define EPC_1 177 -#define EPC_2 178 -#define EPC_3 179 -#define EPC_4 180 -#define EPC_5 181 -#define EPC_6 182 -#define EPC_7 183 -#define DEPC 192 -#define EPS_2 194 -#define EPS_3 195 -#define EPS_4 196 -#define EPS_5 197 -#define EPS_6 198 -#define EPS_7 199 -#define EXCSAVE_1 209 -#define EXCSAVE_2 210 -#define EXCSAVE_3 211 -#define EXCSAVE_4 212 -#define EXCSAVE_5 213 -#define EXCSAVE_6 214 -#define EXCSAVE_7 215 -#define CPENABLE 224 -#define INTERRUPT 226 -#define INTREAD INTERRUPT /* alternate name for backward compatibility */ -#define INTSET INTERRUPT /* alternate name for backward compatibility */ -#define INTCLEAR 227 -#define INTENABLE 228 -#define PS 230 -#define VECBASE 231 -#define EXCCAUSE 232 -#define DEBUGCAUSE 233 -#define CCOUNT 234 -#define PRID 235 -#define ICOUNT 236 -#define ICOUNTLEVEL 237 -#define EXCVADDR 238 -#define CCOMPARE_0 240 -#define CCOMPARE_1 241 -#define CCOMPARE_2 242 -#define MISC_REG_0 244 -#define MISC_REG_1 245 -#define MISC_REG_2 246 -#define MISC_REG_3 247 - -/* Special cases (bases of special register series): */ -#define MR 32 -#define IBREAKA 128 -#define DBREAKA 144 -#define DBREAKC 160 -#define EPC 176 -#define EPS 192 -#define EXCSAVE 208 -#define CCOMPARE 240 -#define MISC_REG 244 - -/* Tensilica-defined user registers: */ -#if 0 -/*#define ... 21..24 */ /* (545CK) */ -/*#define ... 140..143 */ /* (545CK) */ -#define EXPSTATE 230 /* Diamond */ -#define THREADPTR 231 /* threadptr option */ -#define FCR 232 /* FPU */ -#define FSR 233 /* FPU */ -#define AE_OVF_SAR 240 /* HiFi2 */ -#define AE_BITHEAD 241 /* HiFi2 */ -#define AE_TS_FTS_BU_BP 242 /* HiFi2 */ -#define AE_SD_NO 243 /* HiFi2 */ -#define VSAR 240 /* VectraLX */ -#define ROUND_LO 242 /* VectraLX */ -#define ROUND_HI 243 /* VectraLX */ -#define CBEGIN 246 /* VectraLX */ -#define CEND 247 /* VectraLX */ -#endif - -#endif /* XTENSA_SPECREG_H */ - +/* + * Xtensa Special Register symbolic names + */ + +/* $Id: //depot/rel/Boreal/Xtensa/OS/include/xtensa/specreg.h#2 $ */ + +/* + * Copyright (c) 2005-2010 Tensilica Inc. + * + * 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 XTENSA_SPECREG_H +#define XTENSA_SPECREG_H + +/* Special registers: */ +#define LBEG 0 +#define LEND 1 +#define LCOUNT 2 +#define SAR 3 +#define BR 4 +#define LITBASE 5 +#define SCOMPARE1 12 +#define ACCLO 16 +#define ACCHI 17 +#define MR_0 32 +#define MR_1 33 +#define MR_2 34 +#define MR_3 35 +#define PREFCTL 40 +#define WINDOWBASE 72 +#define WINDOWSTART 73 +#define PTEVADDR 83 +#define RASID 90 +#define ITLBCFG 91 +#define DTLBCFG 92 +#define IBREAKENABLE 96 +#define CACHEATTR 98 +#define DDR 104 +#define IBREAKA_0 128 +#define IBREAKA_1 129 +#define DBREAKA_0 144 +#define DBREAKA_1 145 +#define DBREAKC_0 160 +#define DBREAKC_1 161 +#define EPC_1 177 +#define EPC_2 178 +#define EPC_3 179 +#define EPC_4 180 +#define EPC_5 181 +#define EPC_6 182 +#define EPC_7 183 +#define DEPC 192 +#define EPS_2 194 +#define EPS_3 195 +#define EPS_4 196 +#define EPS_5 197 +#define EPS_6 198 +#define EPS_7 199 +#define EXCSAVE_1 209 +#define EXCSAVE_2 210 +#define EXCSAVE_3 211 +#define EXCSAVE_4 212 +#define EXCSAVE_5 213 +#define EXCSAVE_6 214 +#define EXCSAVE_7 215 +#define CPENABLE 224 +#define INTERRUPT 226 +#define INTREAD INTERRUPT /* alternate name for backward compatibility */ +#define INTSET INTERRUPT /* alternate name for backward compatibility */ +#define INTCLEAR 227 +#define INTENABLE 228 +#define PS 230 +#define VECBASE 231 +#define EXCCAUSE 232 +#define DEBUGCAUSE 233 +#define CCOUNT 234 +#define PRID 235 +#define ICOUNT 236 +#define ICOUNTLEVEL 237 +#define EXCVADDR 238 +#define CCOMPARE_0 240 +#define CCOMPARE_1 241 +#define CCOMPARE_2 242 +#define MISC_REG_0 244 +#define MISC_REG_1 245 +#define MISC_REG_2 246 +#define MISC_REG_3 247 + +/* Special cases (bases of special register series): */ +#define MR 32 +#define IBREAKA 128 +#define DBREAKA 144 +#define DBREAKC 160 +#define EPC 176 +#define EPS 192 +#define EXCSAVE 208 +#define CCOMPARE 240 +#define MISC_REG 244 + +/* Tensilica-defined user registers: */ +#if 0 +/*#define ... 21..24 */ /* (545CK) */ +/*#define ... 140..143 */ /* (545CK) */ +#define EXPSTATE 230 /* Diamond */ +#define THREADPTR 231 /* threadptr option */ +#define FCR 232 /* FPU */ +#define FSR 233 /* FPU */ +#define AE_OVF_SAR 240 /* HiFi2 */ +#define AE_BITHEAD 241 /* HiFi2 */ +#define AE_TS_FTS_BU_BP 242 /* HiFi2 */ +#define AE_SD_NO 243 /* HiFi2 */ +#define VSAR 240 /* VectraLX */ +#define ROUND_LO 242 /* VectraLX */ +#define ROUND_HI 243 /* VectraLX */ +#define CBEGIN 246 /* VectraLX */ +#define CEND 247 /* VectraLX */ +#endif + +#endif /* XTENSA_SPECREG_H */ + diff --git a/extra_include/xtensa/tie/xt_MUL32.h b/extra_include/xtensa/tie/xt_MUL32.h index a2dea412..eb3824e6 100644 --- a/extra_include/xtensa/tie/xt_MUL32.h +++ b/extra_include/xtensa/tie/xt_MUL32.h @@ -1,24 +1,24 @@ -/* Definitions for the 32-bit Integer Multiply Option. */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2009 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* NOTE: This file exists only for backward compatibility with RB-200X.x - and earlier Xtensa releases. Starting with RC-2009.0 you should use - . */ - -#ifndef _XTENSA_xt_MUL32_HEADER -#define _XTENSA_xt_MUL32_HEADER - -#ifdef __XTENSA__ - -#include - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_MUL32_HEADER */ +/* Definitions for the 32-bit Integer Multiply Option. */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2009 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* NOTE: This file exists only for backward compatibility with RB-200X.x + and earlier Xtensa releases. Starting with RC-2009.0 you should use + . */ + +#ifndef _XTENSA_xt_MUL32_HEADER +#define _XTENSA_xt_MUL32_HEADER + +#ifdef __XTENSA__ + +#include + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_MUL32_HEADER */ diff --git a/extra_include/xtensa/tie/xt_core.h b/extra_include/xtensa/tie/xt_core.h index 796f73f0..77e65a29 100644 --- a/extra_include/xtensa/tie/xt_core.h +++ b/extra_include/xtensa/tie/xt_core.h @@ -1,254 +1,254 @@ -/* Definitions for the xt_core TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_core_HEADER -#define _XTENSA_xt_core_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern void _TIE_xt_core_ILL(void); -extern void _TIE_xt_core_NOP(void); -extern void _TIE_xt_core_MEMW(void); -extern void _TIE_xt_core_EXTW(void); -extern void _TIE_xt_core_ISYNC(void); -extern void _TIE_xt_core_DSYNC(void); -extern void _TIE_xt_core_ESYNC(void); -extern void _TIE_xt_core_RSYNC(void); -extern unsigned _TIE_xt_core_RSR_176(void); -extern void _TIE_xt_core_WSR_176(unsigned art); -extern unsigned _TIE_xt_core_RSR_208(void); -extern unsigned _TIE_xt_core_uint32_loadi(const unsigned * p, immediate o); -extern void _TIE_xt_core_uint32_storei(unsigned c, unsigned * p, immediate o); -extern unsigned _TIE_xt_core_uint32_move(unsigned b); -extern int _TIE_xt_core_ADDI(int s, immediate i); -extern int _TIE_xt_core_OR(int s, int t); -extern int _TIE_xt_core_L32I(const int * p, immediate i); -extern void _TIE_xt_core_S32I(int r, int * p, immediate i); -extern unsigned char _TIE_xt_core_L8UI(const unsigned char * p, immediate i); -extern void _TIE_xt_core_S8I(signed char r, signed char * p, immediate i); -extern unsigned short _TIE_xt_core_L16UI(const unsigned short * p, immediate i); -extern short _TIE_xt_core_L16SI(const short * p, immediate i); -extern void _TIE_xt_core_S16I(short r, short * p, immediate i); -extern int _TIE_xt_core_ADDMI(int s, immediate i); -extern int _TIE_xt_core_ADD(int s, int t); -extern int _TIE_xt_core_ADDX2(int s, int t); -extern int _TIE_xt_core_ADDX4(int s, int t); -extern int _TIE_xt_core_ADDX8(int s, int t); -extern int _TIE_xt_core_SUB(int s, int t); -extern int _TIE_xt_core_SUBX2(int s, int t); -extern int _TIE_xt_core_SUBX4(int s, int t); -extern int _TIE_xt_core_SUBX8(int s, int t); -extern int _TIE_xt_core_AND(int s, int t); -extern int _TIE_xt_core_XOR(int s, int t); -extern unsigned _TIE_xt_core_EXTUI(unsigned t, immediate i, immediate o); -extern int _TIE_xt_core_MOVI(immediate i); -extern void _TIE_xt_core_MOVEQZ(int r /*inout*/, int s, int t); -extern void _TIE_xt_core_MOVNEZ(int r /*inout*/, int s, int t); -extern void _TIE_xt_core_MOVLTZ(int r /*inout*/, int s, int t); -extern void _TIE_xt_core_MOVGEZ(int r /*inout*/, int s, int t); -extern int _TIE_xt_core_NEG(int t); -extern int _TIE_xt_core_ABS(int t); -extern void _TIE_xt_core_SSR(int s); -extern void _TIE_xt_core_SSL(int s); -extern void _TIE_xt_core_SSA8L(int s); -extern void _TIE_xt_core_SSA8B(int s); -extern void _TIE_xt_core_SSAI(immediate i); -extern int _TIE_xt_core_SLL(int s); -extern int _TIE_xt_core_SRC(int s, int t); -extern unsigned _TIE_xt_core_SRL(unsigned t); -extern int _TIE_xt_core_SRA(int t); -extern int _TIE_xt_core_SLLI(int s, immediate i); -extern int _TIE_xt_core_SRAI(int t, immediate i); -extern unsigned _TIE_xt_core_SRLI(unsigned t, immediate i); -extern int _TIE_xt_core_SSAI_SRC(int src1, int src2, immediate amount); -extern int _TIE_xt_core_SSR_SRC(int src1, int src2, int amount); -extern int _TIE_xt_core_WSR_SAR_SRC(int src1, int src2, int amount); -extern int _TIE_xt_core_SSR_SRA(int src, int amount); -extern unsigned _TIE_xt_core_SSR_SRL(unsigned src, int amount); -extern int _TIE_xt_core_SSL_SLL(int src, int amount); -extern int _TIE_xt_core_RSIL(immediate t); -extern unsigned _TIE_xt_core_RSR_SAR(void); -extern void _TIE_xt_core_WSR_SAR(unsigned t); -extern void _TIE_xt_core_XSR_SAR(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_LITBASE(void); -extern void _TIE_xt_core_WSR_LITBASE(unsigned t); -extern void _TIE_xt_core_XSR_LITBASE(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_PS(void); -extern void _TIE_xt_core_WSR_PS(unsigned t); -extern void _TIE_xt_core_XSR_PS(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_EPC1(void); -extern void _TIE_xt_core_WSR_EPC1(unsigned t); -extern void _TIE_xt_core_XSR_EPC1(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_EXCSAVE1(void); -extern void _TIE_xt_core_WSR_EXCSAVE1(unsigned t); -extern void _TIE_xt_core_XSR_EXCSAVE1(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_EPC2(void); -extern void _TIE_xt_core_WSR_EPC2(unsigned t); -extern void _TIE_xt_core_XSR_EPC2(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_EXCSAVE2(void); -extern void _TIE_xt_core_WSR_EXCSAVE2(unsigned t); -extern void _TIE_xt_core_XSR_EXCSAVE2(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_EPC3(void); -extern void _TIE_xt_core_WSR_EPC3(unsigned t); -extern void _TIE_xt_core_XSR_EPC3(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_EXCSAVE3(void); -extern void _TIE_xt_core_WSR_EXCSAVE3(unsigned t); -extern void _TIE_xt_core_XSR_EXCSAVE3(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_VECBASE(void); -extern void _TIE_xt_core_WSR_VECBASE(unsigned t); -extern void _TIE_xt_core_XSR_VECBASE(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_EPS2(void); -extern void _TIE_xt_core_WSR_EPS2(unsigned t); -extern void _TIE_xt_core_XSR_EPS2(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_EPS3(void); -extern void _TIE_xt_core_WSR_EPS3(unsigned t); -extern void _TIE_xt_core_XSR_EPS3(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_EXCCAUSE(void); -extern void _TIE_xt_core_WSR_EXCCAUSE(unsigned t); -extern void _TIE_xt_core_XSR_EXCCAUSE(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_EXCVADDR(void); -extern void _TIE_xt_core_WSR_EXCVADDR(unsigned t); -extern void _TIE_xt_core_XSR_EXCVADDR(unsigned t /*inout*/); -extern unsigned _TIE_xt_core_RSR_DEPC(void); -extern void _TIE_xt_core_WSR_DEPC(unsigned t); -extern void _TIE_xt_core_XSR_DEPC(unsigned t /*inout*/); -extern int _TIE_xt_core_RSR_PRID(void); -#define XT_ILL _TIE_xt_core_ILL -#define XT_NOP _TIE_xt_core_NOP -#define XT_MEMW _TIE_xt_core_MEMW -#define XT_EXTW _TIE_xt_core_EXTW -#define XT_ISYNC _TIE_xt_core_ISYNC -#define XT_DSYNC _TIE_xt_core_DSYNC -#define XT_ESYNC _TIE_xt_core_ESYNC -#define XT_RSYNC _TIE_xt_core_RSYNC -#define XT_RSR_176 _TIE_xt_core_RSR_176 -#define XT_WSR_176 _TIE_xt_core_WSR_176 -#define XT_RSR_208 _TIE_xt_core_RSR_208 -#define XT_uint32_loadi _TIE_xt_core_uint32_loadi -#define XT_uint32_storei _TIE_xt_core_uint32_storei -#define XT_uint32_move _TIE_xt_core_uint32_move -#define XT_ADDI _TIE_xt_core_ADDI -#define XT_OR _TIE_xt_core_OR -#define XT_L32I _TIE_xt_core_L32I -#define XT_S32I _TIE_xt_core_S32I -#define XT_L8UI _TIE_xt_core_L8UI -#define XT_S8I _TIE_xt_core_S8I -#define XT_L16UI _TIE_xt_core_L16UI -#define XT_L16SI _TIE_xt_core_L16SI -#define XT_S16I _TIE_xt_core_S16I -#define XT_ADDMI _TIE_xt_core_ADDMI -#define XT_ADD _TIE_xt_core_ADD -#define XT_ADDX2 _TIE_xt_core_ADDX2 -#define XT_ADDX4 _TIE_xt_core_ADDX4 -#define XT_ADDX8 _TIE_xt_core_ADDX8 -#define XT_SUB _TIE_xt_core_SUB -#define XT_SUBX2 _TIE_xt_core_SUBX2 -#define XT_SUBX4 _TIE_xt_core_SUBX4 -#define XT_SUBX8 _TIE_xt_core_SUBX8 -#define XT_AND _TIE_xt_core_AND -#define XT_XOR _TIE_xt_core_XOR -#define XT_EXTUI _TIE_xt_core_EXTUI -#define XT_MOVI _TIE_xt_core_MOVI -#define XT_MOVEQZ _TIE_xt_core_MOVEQZ -#define XT_MOVNEZ _TIE_xt_core_MOVNEZ -#define XT_MOVLTZ _TIE_xt_core_MOVLTZ -#define XT_MOVGEZ _TIE_xt_core_MOVGEZ -#define XT_NEG _TIE_xt_core_NEG -#define XT_ABS _TIE_xt_core_ABS -#define XT_SSR _TIE_xt_core_SSR -#define XT_SSL _TIE_xt_core_SSL -#define XT_SSA8L _TIE_xt_core_SSA8L -#define XT_SSA8B _TIE_xt_core_SSA8B -#define XT_SSAI _TIE_xt_core_SSAI -#define XT_SLL _TIE_xt_core_SLL -#define XT_SRC _TIE_xt_core_SRC -#define XT_SRL _TIE_xt_core_SRL -#define XT_SRA _TIE_xt_core_SRA -#define XT_SLLI _TIE_xt_core_SLLI -#define XT_SRAI _TIE_xt_core_SRAI -#define XT_SRLI _TIE_xt_core_SRLI -#define XT_SSAI_SRC _TIE_xt_core_SSAI_SRC -#define XT_SSR_SRC _TIE_xt_core_SSR_SRC -#define XT_WSR_SAR_SRC _TIE_xt_core_WSR_SAR_SRC -#define XT_SSR_SRA _TIE_xt_core_SSR_SRA -#define XT_SSR_SRL _TIE_xt_core_SSR_SRL -#define XT_SSL_SLL _TIE_xt_core_SSL_SLL -#define XT_RSIL _TIE_xt_core_RSIL -#define XT_RSR_SAR _TIE_xt_core_RSR_SAR -#define XT_WSR_SAR _TIE_xt_core_WSR_SAR -#define XT_XSR_SAR _TIE_xt_core_XSR_SAR -#define XT_RSR_LITBASE _TIE_xt_core_RSR_LITBASE -#define XT_WSR_LITBASE _TIE_xt_core_WSR_LITBASE -#define XT_XSR_LITBASE _TIE_xt_core_XSR_LITBASE -#define XT_RSR_PS _TIE_xt_core_RSR_PS -#define XT_WSR_PS _TIE_xt_core_WSR_PS -#define XT_XSR_PS _TIE_xt_core_XSR_PS -#define XT_RSR_EPC1 _TIE_xt_core_RSR_EPC1 -#define XT_WSR_EPC1 _TIE_xt_core_WSR_EPC1 -#define XT_XSR_EPC1 _TIE_xt_core_XSR_EPC1 -#define XT_RSR_EXCSAVE1 _TIE_xt_core_RSR_EXCSAVE1 -#define XT_WSR_EXCSAVE1 _TIE_xt_core_WSR_EXCSAVE1 -#define XT_XSR_EXCSAVE1 _TIE_xt_core_XSR_EXCSAVE1 -#define XT_RSR_EPC2 _TIE_xt_core_RSR_EPC2 -#define XT_WSR_EPC2 _TIE_xt_core_WSR_EPC2 -#define XT_XSR_EPC2 _TIE_xt_core_XSR_EPC2 -#define XT_RSR_EXCSAVE2 _TIE_xt_core_RSR_EXCSAVE2 -#define XT_WSR_EXCSAVE2 _TIE_xt_core_WSR_EXCSAVE2 -#define XT_XSR_EXCSAVE2 _TIE_xt_core_XSR_EXCSAVE2 -#define XT_RSR_EPC3 _TIE_xt_core_RSR_EPC3 -#define XT_WSR_EPC3 _TIE_xt_core_WSR_EPC3 -#define XT_XSR_EPC3 _TIE_xt_core_XSR_EPC3 -#define XT_RSR_EXCSAVE3 _TIE_xt_core_RSR_EXCSAVE3 -#define XT_WSR_EXCSAVE3 _TIE_xt_core_WSR_EXCSAVE3 -#define XT_XSR_EXCSAVE3 _TIE_xt_core_XSR_EXCSAVE3 -#define XT_RSR_VECBASE _TIE_xt_core_RSR_VECBASE -#define XT_WSR_VECBASE _TIE_xt_core_WSR_VECBASE -#define XT_XSR_VECBASE _TIE_xt_core_XSR_VECBASE -#define XT_RSR_EPS2 _TIE_xt_core_RSR_EPS2 -#define XT_WSR_EPS2 _TIE_xt_core_WSR_EPS2 -#define XT_XSR_EPS2 _TIE_xt_core_XSR_EPS2 -#define XT_RSR_EPS3 _TIE_xt_core_RSR_EPS3 -#define XT_WSR_EPS3 _TIE_xt_core_WSR_EPS3 -#define XT_XSR_EPS3 _TIE_xt_core_XSR_EPS3 -#define XT_RSR_EXCCAUSE _TIE_xt_core_RSR_EXCCAUSE -#define XT_WSR_EXCCAUSE _TIE_xt_core_WSR_EXCCAUSE -#define XT_XSR_EXCCAUSE _TIE_xt_core_XSR_EXCCAUSE -#define XT_RSR_EXCVADDR _TIE_xt_core_RSR_EXCVADDR -#define XT_WSR_EXCVADDR _TIE_xt_core_WSR_EXCVADDR -#define XT_XSR_EXCVADDR _TIE_xt_core_XSR_EXCVADDR -#define XT_RSR_DEPC _TIE_xt_core_RSR_DEPC -#define XT_WSR_DEPC _TIE_xt_core_WSR_DEPC -#define XT_XSR_DEPC _TIE_xt_core_XSR_DEPC -#define XT_RSR_PRID _TIE_xt_core_RSR_PRID - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_core_HEADER */ +/* Definitions for the xt_core TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_core_HEADER +#define _XTENSA_xt_core_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern void _TIE_xt_core_ILL(void); +extern void _TIE_xt_core_NOP(void); +extern void _TIE_xt_core_MEMW(void); +extern void _TIE_xt_core_EXTW(void); +extern void _TIE_xt_core_ISYNC(void); +extern void _TIE_xt_core_DSYNC(void); +extern void _TIE_xt_core_ESYNC(void); +extern void _TIE_xt_core_RSYNC(void); +extern unsigned _TIE_xt_core_RSR_176(void); +extern void _TIE_xt_core_WSR_176(unsigned art); +extern unsigned _TIE_xt_core_RSR_208(void); +extern unsigned _TIE_xt_core_uint32_loadi(const unsigned * p, immediate o); +extern void _TIE_xt_core_uint32_storei(unsigned c, unsigned * p, immediate o); +extern unsigned _TIE_xt_core_uint32_move(unsigned b); +extern int _TIE_xt_core_ADDI(int s, immediate i); +extern int _TIE_xt_core_OR(int s, int t); +extern int _TIE_xt_core_L32I(const int * p, immediate i); +extern void _TIE_xt_core_S32I(int r, int * p, immediate i); +extern unsigned char _TIE_xt_core_L8UI(const unsigned char * p, immediate i); +extern void _TIE_xt_core_S8I(signed char r, signed char * p, immediate i); +extern unsigned short _TIE_xt_core_L16UI(const unsigned short * p, immediate i); +extern short _TIE_xt_core_L16SI(const short * p, immediate i); +extern void _TIE_xt_core_S16I(short r, short * p, immediate i); +extern int _TIE_xt_core_ADDMI(int s, immediate i); +extern int _TIE_xt_core_ADD(int s, int t); +extern int _TIE_xt_core_ADDX2(int s, int t); +extern int _TIE_xt_core_ADDX4(int s, int t); +extern int _TIE_xt_core_ADDX8(int s, int t); +extern int _TIE_xt_core_SUB(int s, int t); +extern int _TIE_xt_core_SUBX2(int s, int t); +extern int _TIE_xt_core_SUBX4(int s, int t); +extern int _TIE_xt_core_SUBX8(int s, int t); +extern int _TIE_xt_core_AND(int s, int t); +extern int _TIE_xt_core_XOR(int s, int t); +extern unsigned _TIE_xt_core_EXTUI(unsigned t, immediate i, immediate o); +extern int _TIE_xt_core_MOVI(immediate i); +extern void _TIE_xt_core_MOVEQZ(int r /*inout*/, int s, int t); +extern void _TIE_xt_core_MOVNEZ(int r /*inout*/, int s, int t); +extern void _TIE_xt_core_MOVLTZ(int r /*inout*/, int s, int t); +extern void _TIE_xt_core_MOVGEZ(int r /*inout*/, int s, int t); +extern int _TIE_xt_core_NEG(int t); +extern int _TIE_xt_core_ABS(int t); +extern void _TIE_xt_core_SSR(int s); +extern void _TIE_xt_core_SSL(int s); +extern void _TIE_xt_core_SSA8L(int s); +extern void _TIE_xt_core_SSA8B(int s); +extern void _TIE_xt_core_SSAI(immediate i); +extern int _TIE_xt_core_SLL(int s); +extern int _TIE_xt_core_SRC(int s, int t); +extern unsigned _TIE_xt_core_SRL(unsigned t); +extern int _TIE_xt_core_SRA(int t); +extern int _TIE_xt_core_SLLI(int s, immediate i); +extern int _TIE_xt_core_SRAI(int t, immediate i); +extern unsigned _TIE_xt_core_SRLI(unsigned t, immediate i); +extern int _TIE_xt_core_SSAI_SRC(int src1, int src2, immediate amount); +extern int _TIE_xt_core_SSR_SRC(int src1, int src2, int amount); +extern int _TIE_xt_core_WSR_SAR_SRC(int src1, int src2, int amount); +extern int _TIE_xt_core_SSR_SRA(int src, int amount); +extern unsigned _TIE_xt_core_SSR_SRL(unsigned src, int amount); +extern int _TIE_xt_core_SSL_SLL(int src, int amount); +extern int _TIE_xt_core_RSIL(immediate t); +extern unsigned _TIE_xt_core_RSR_SAR(void); +extern void _TIE_xt_core_WSR_SAR(unsigned t); +extern void _TIE_xt_core_XSR_SAR(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_LITBASE(void); +extern void _TIE_xt_core_WSR_LITBASE(unsigned t); +extern void _TIE_xt_core_XSR_LITBASE(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_PS(void); +extern void _TIE_xt_core_WSR_PS(unsigned t); +extern void _TIE_xt_core_XSR_PS(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_EPC1(void); +extern void _TIE_xt_core_WSR_EPC1(unsigned t); +extern void _TIE_xt_core_XSR_EPC1(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_EXCSAVE1(void); +extern void _TIE_xt_core_WSR_EXCSAVE1(unsigned t); +extern void _TIE_xt_core_XSR_EXCSAVE1(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_EPC2(void); +extern void _TIE_xt_core_WSR_EPC2(unsigned t); +extern void _TIE_xt_core_XSR_EPC2(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_EXCSAVE2(void); +extern void _TIE_xt_core_WSR_EXCSAVE2(unsigned t); +extern void _TIE_xt_core_XSR_EXCSAVE2(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_EPC3(void); +extern void _TIE_xt_core_WSR_EPC3(unsigned t); +extern void _TIE_xt_core_XSR_EPC3(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_EXCSAVE3(void); +extern void _TIE_xt_core_WSR_EXCSAVE3(unsigned t); +extern void _TIE_xt_core_XSR_EXCSAVE3(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_VECBASE(void); +extern void _TIE_xt_core_WSR_VECBASE(unsigned t); +extern void _TIE_xt_core_XSR_VECBASE(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_EPS2(void); +extern void _TIE_xt_core_WSR_EPS2(unsigned t); +extern void _TIE_xt_core_XSR_EPS2(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_EPS3(void); +extern void _TIE_xt_core_WSR_EPS3(unsigned t); +extern void _TIE_xt_core_XSR_EPS3(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_EXCCAUSE(void); +extern void _TIE_xt_core_WSR_EXCCAUSE(unsigned t); +extern void _TIE_xt_core_XSR_EXCCAUSE(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_EXCVADDR(void); +extern void _TIE_xt_core_WSR_EXCVADDR(unsigned t); +extern void _TIE_xt_core_XSR_EXCVADDR(unsigned t /*inout*/); +extern unsigned _TIE_xt_core_RSR_DEPC(void); +extern void _TIE_xt_core_WSR_DEPC(unsigned t); +extern void _TIE_xt_core_XSR_DEPC(unsigned t /*inout*/); +extern int _TIE_xt_core_RSR_PRID(void); +#define XT_ILL _TIE_xt_core_ILL +#define XT_NOP _TIE_xt_core_NOP +#define XT_MEMW _TIE_xt_core_MEMW +#define XT_EXTW _TIE_xt_core_EXTW +#define XT_ISYNC _TIE_xt_core_ISYNC +#define XT_DSYNC _TIE_xt_core_DSYNC +#define XT_ESYNC _TIE_xt_core_ESYNC +#define XT_RSYNC _TIE_xt_core_RSYNC +#define XT_RSR_176 _TIE_xt_core_RSR_176 +#define XT_WSR_176 _TIE_xt_core_WSR_176 +#define XT_RSR_208 _TIE_xt_core_RSR_208 +#define XT_uint32_loadi _TIE_xt_core_uint32_loadi +#define XT_uint32_storei _TIE_xt_core_uint32_storei +#define XT_uint32_move _TIE_xt_core_uint32_move +#define XT_ADDI _TIE_xt_core_ADDI +#define XT_OR _TIE_xt_core_OR +#define XT_L32I _TIE_xt_core_L32I +#define XT_S32I _TIE_xt_core_S32I +#define XT_L8UI _TIE_xt_core_L8UI +#define XT_S8I _TIE_xt_core_S8I +#define XT_L16UI _TIE_xt_core_L16UI +#define XT_L16SI _TIE_xt_core_L16SI +#define XT_S16I _TIE_xt_core_S16I +#define XT_ADDMI _TIE_xt_core_ADDMI +#define XT_ADD _TIE_xt_core_ADD +#define XT_ADDX2 _TIE_xt_core_ADDX2 +#define XT_ADDX4 _TIE_xt_core_ADDX4 +#define XT_ADDX8 _TIE_xt_core_ADDX8 +#define XT_SUB _TIE_xt_core_SUB +#define XT_SUBX2 _TIE_xt_core_SUBX2 +#define XT_SUBX4 _TIE_xt_core_SUBX4 +#define XT_SUBX8 _TIE_xt_core_SUBX8 +#define XT_AND _TIE_xt_core_AND +#define XT_XOR _TIE_xt_core_XOR +#define XT_EXTUI _TIE_xt_core_EXTUI +#define XT_MOVI _TIE_xt_core_MOVI +#define XT_MOVEQZ _TIE_xt_core_MOVEQZ +#define XT_MOVNEZ _TIE_xt_core_MOVNEZ +#define XT_MOVLTZ _TIE_xt_core_MOVLTZ +#define XT_MOVGEZ _TIE_xt_core_MOVGEZ +#define XT_NEG _TIE_xt_core_NEG +#define XT_ABS _TIE_xt_core_ABS +#define XT_SSR _TIE_xt_core_SSR +#define XT_SSL _TIE_xt_core_SSL +#define XT_SSA8L _TIE_xt_core_SSA8L +#define XT_SSA8B _TIE_xt_core_SSA8B +#define XT_SSAI _TIE_xt_core_SSAI +#define XT_SLL _TIE_xt_core_SLL +#define XT_SRC _TIE_xt_core_SRC +#define XT_SRL _TIE_xt_core_SRL +#define XT_SRA _TIE_xt_core_SRA +#define XT_SLLI _TIE_xt_core_SLLI +#define XT_SRAI _TIE_xt_core_SRAI +#define XT_SRLI _TIE_xt_core_SRLI +#define XT_SSAI_SRC _TIE_xt_core_SSAI_SRC +#define XT_SSR_SRC _TIE_xt_core_SSR_SRC +#define XT_WSR_SAR_SRC _TIE_xt_core_WSR_SAR_SRC +#define XT_SSR_SRA _TIE_xt_core_SSR_SRA +#define XT_SSR_SRL _TIE_xt_core_SSR_SRL +#define XT_SSL_SLL _TIE_xt_core_SSL_SLL +#define XT_RSIL _TIE_xt_core_RSIL +#define XT_RSR_SAR _TIE_xt_core_RSR_SAR +#define XT_WSR_SAR _TIE_xt_core_WSR_SAR +#define XT_XSR_SAR _TIE_xt_core_XSR_SAR +#define XT_RSR_LITBASE _TIE_xt_core_RSR_LITBASE +#define XT_WSR_LITBASE _TIE_xt_core_WSR_LITBASE +#define XT_XSR_LITBASE _TIE_xt_core_XSR_LITBASE +#define XT_RSR_PS _TIE_xt_core_RSR_PS +#define XT_WSR_PS _TIE_xt_core_WSR_PS +#define XT_XSR_PS _TIE_xt_core_XSR_PS +#define XT_RSR_EPC1 _TIE_xt_core_RSR_EPC1 +#define XT_WSR_EPC1 _TIE_xt_core_WSR_EPC1 +#define XT_XSR_EPC1 _TIE_xt_core_XSR_EPC1 +#define XT_RSR_EXCSAVE1 _TIE_xt_core_RSR_EXCSAVE1 +#define XT_WSR_EXCSAVE1 _TIE_xt_core_WSR_EXCSAVE1 +#define XT_XSR_EXCSAVE1 _TIE_xt_core_XSR_EXCSAVE1 +#define XT_RSR_EPC2 _TIE_xt_core_RSR_EPC2 +#define XT_WSR_EPC2 _TIE_xt_core_WSR_EPC2 +#define XT_XSR_EPC2 _TIE_xt_core_XSR_EPC2 +#define XT_RSR_EXCSAVE2 _TIE_xt_core_RSR_EXCSAVE2 +#define XT_WSR_EXCSAVE2 _TIE_xt_core_WSR_EXCSAVE2 +#define XT_XSR_EXCSAVE2 _TIE_xt_core_XSR_EXCSAVE2 +#define XT_RSR_EPC3 _TIE_xt_core_RSR_EPC3 +#define XT_WSR_EPC3 _TIE_xt_core_WSR_EPC3 +#define XT_XSR_EPC3 _TIE_xt_core_XSR_EPC3 +#define XT_RSR_EXCSAVE3 _TIE_xt_core_RSR_EXCSAVE3 +#define XT_WSR_EXCSAVE3 _TIE_xt_core_WSR_EXCSAVE3 +#define XT_XSR_EXCSAVE3 _TIE_xt_core_XSR_EXCSAVE3 +#define XT_RSR_VECBASE _TIE_xt_core_RSR_VECBASE +#define XT_WSR_VECBASE _TIE_xt_core_WSR_VECBASE +#define XT_XSR_VECBASE _TIE_xt_core_XSR_VECBASE +#define XT_RSR_EPS2 _TIE_xt_core_RSR_EPS2 +#define XT_WSR_EPS2 _TIE_xt_core_WSR_EPS2 +#define XT_XSR_EPS2 _TIE_xt_core_XSR_EPS2 +#define XT_RSR_EPS3 _TIE_xt_core_RSR_EPS3 +#define XT_WSR_EPS3 _TIE_xt_core_WSR_EPS3 +#define XT_XSR_EPS3 _TIE_xt_core_XSR_EPS3 +#define XT_RSR_EXCCAUSE _TIE_xt_core_RSR_EXCCAUSE +#define XT_WSR_EXCCAUSE _TIE_xt_core_WSR_EXCCAUSE +#define XT_XSR_EXCCAUSE _TIE_xt_core_XSR_EXCCAUSE +#define XT_RSR_EXCVADDR _TIE_xt_core_RSR_EXCVADDR +#define XT_WSR_EXCVADDR _TIE_xt_core_WSR_EXCVADDR +#define XT_XSR_EXCVADDR _TIE_xt_core_XSR_EXCVADDR +#define XT_RSR_DEPC _TIE_xt_core_RSR_DEPC +#define XT_WSR_DEPC _TIE_xt_core_WSR_DEPC +#define XT_XSR_DEPC _TIE_xt_core_XSR_DEPC +#define XT_RSR_PRID _TIE_xt_core_RSR_PRID + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_core_HEADER */ diff --git a/extra_include/xtensa/tie/xt_debug.h b/extra_include/xtensa/tie/xt_debug.h index 7d57acff..b6e322af 100644 --- a/extra_include/xtensa/tie/xt_debug.h +++ b/extra_include/xtensa/tie/xt_debug.h @@ -1,93 +1,93 @@ -/* Definitions for the xt_debug TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_debug_HEADER -#define _XTENSA_xt_debug_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - -#include - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern void _TIE_xt_debug_BREAK(immediate imms, immediate immt); -extern void _TIE_xt_debug_BREAK_N(immediate imms); -extern unsigned _TIE_xt_debug_RSR_DBREAKA0(void); -extern void _TIE_xt_debug_WSR_DBREAKA0(unsigned art); -extern void _TIE_xt_debug_XSR_DBREAKA0(unsigned art /*inout*/); -extern unsigned _TIE_xt_debug_RSR_DBREAKC0(void); -extern void _TIE_xt_debug_WSR_DBREAKC0(unsigned art); -extern void _TIE_xt_debug_XSR_DBREAKC0(unsigned art /*inout*/); -extern unsigned _TIE_xt_debug_RSR_IBREAKA0(void); -extern void _TIE_xt_debug_WSR_IBREAKA0(unsigned art); -extern void _TIE_xt_debug_XSR_IBREAKA0(unsigned art /*inout*/); -extern unsigned _TIE_xt_debug_RSR_IBREAKENABLE(void); -extern void _TIE_xt_debug_WSR_IBREAKENABLE(unsigned art); -extern void _TIE_xt_debug_XSR_IBREAKENABLE(unsigned art /*inout*/); -extern unsigned _TIE_xt_debug_RSR_DEBUGCAUSE(void); -extern void _TIE_xt_debug_WSR_DEBUGCAUSE(unsigned art); -extern void _TIE_xt_debug_XSR_DEBUGCAUSE(unsigned art /*inout*/); -extern unsigned _TIE_xt_debug_RSR_ICOUNT(void); -extern void _TIE_xt_debug_WSR_ICOUNT(unsigned art); -extern void _TIE_xt_debug_XSR_ICOUNT(unsigned art /*inout*/); -extern unsigned _TIE_xt_debug_RSR_ICOUNTLEVEL(void); -extern void _TIE_xt_debug_WSR_ICOUNTLEVEL(unsigned art); -extern void _TIE_xt_debug_XSR_ICOUNTLEVEL(unsigned art /*inout*/); -extern unsigned _TIE_xt_debug_RSR_DDR(void); -extern void _TIE_xt_debug_WSR_DDR(unsigned art); -extern void _TIE_xt_debug_XSR_DDR(unsigned art /*inout*/); -#define XT_BREAK _TIE_xt_debug_BREAK -#define XT_BREAK_N _TIE_xt_debug_BREAK_N -#define XT_RSR_DBREAKA0 _TIE_xt_debug_RSR_DBREAKA0 -#define XT_WSR_DBREAKA0 _TIE_xt_debug_WSR_DBREAKA0 -#define XT_XSR_DBREAKA0 _TIE_xt_debug_XSR_DBREAKA0 -#define XT_RSR_DBREAKC0 _TIE_xt_debug_RSR_DBREAKC0 -#define XT_WSR_DBREAKC0 _TIE_xt_debug_WSR_DBREAKC0 -#define XT_XSR_DBREAKC0 _TIE_xt_debug_XSR_DBREAKC0 -#define XT_RSR_IBREAKA0 _TIE_xt_debug_RSR_IBREAKA0 -#define XT_WSR_IBREAKA0 _TIE_xt_debug_WSR_IBREAKA0 -#define XT_XSR_IBREAKA0 _TIE_xt_debug_XSR_IBREAKA0 -#define XT_RSR_IBREAKENABLE _TIE_xt_debug_RSR_IBREAKENABLE -#define XT_WSR_IBREAKENABLE _TIE_xt_debug_WSR_IBREAKENABLE -#define XT_XSR_IBREAKENABLE _TIE_xt_debug_XSR_IBREAKENABLE -#define XT_RSR_DEBUGCAUSE _TIE_xt_debug_RSR_DEBUGCAUSE -#define XT_WSR_DEBUGCAUSE _TIE_xt_debug_WSR_DEBUGCAUSE -#define XT_XSR_DEBUGCAUSE _TIE_xt_debug_XSR_DEBUGCAUSE -#define XT_RSR_ICOUNT _TIE_xt_debug_RSR_ICOUNT -#define XT_WSR_ICOUNT _TIE_xt_debug_WSR_ICOUNT -#define XT_XSR_ICOUNT _TIE_xt_debug_XSR_ICOUNT -#define XT_RSR_ICOUNTLEVEL _TIE_xt_debug_RSR_ICOUNTLEVEL -#define XT_WSR_ICOUNTLEVEL _TIE_xt_debug_WSR_ICOUNTLEVEL -#define XT_XSR_ICOUNTLEVEL _TIE_xt_debug_XSR_ICOUNTLEVEL -#define XT_RSR_DDR _TIE_xt_debug_RSR_DDR -#define XT_WSR_DDR _TIE_xt_debug_WSR_DDR -#define XT_XSR_DDR _TIE_xt_debug_XSR_DDR - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_debug_HEADER */ +/* Definitions for the xt_debug TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_debug_HEADER +#define _XTENSA_xt_debug_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + +#include + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern void _TIE_xt_debug_BREAK(immediate imms, immediate immt); +extern void _TIE_xt_debug_BREAK_N(immediate imms); +extern unsigned _TIE_xt_debug_RSR_DBREAKA0(void); +extern void _TIE_xt_debug_WSR_DBREAKA0(unsigned art); +extern void _TIE_xt_debug_XSR_DBREAKA0(unsigned art /*inout*/); +extern unsigned _TIE_xt_debug_RSR_DBREAKC0(void); +extern void _TIE_xt_debug_WSR_DBREAKC0(unsigned art); +extern void _TIE_xt_debug_XSR_DBREAKC0(unsigned art /*inout*/); +extern unsigned _TIE_xt_debug_RSR_IBREAKA0(void); +extern void _TIE_xt_debug_WSR_IBREAKA0(unsigned art); +extern void _TIE_xt_debug_XSR_IBREAKA0(unsigned art /*inout*/); +extern unsigned _TIE_xt_debug_RSR_IBREAKENABLE(void); +extern void _TIE_xt_debug_WSR_IBREAKENABLE(unsigned art); +extern void _TIE_xt_debug_XSR_IBREAKENABLE(unsigned art /*inout*/); +extern unsigned _TIE_xt_debug_RSR_DEBUGCAUSE(void); +extern void _TIE_xt_debug_WSR_DEBUGCAUSE(unsigned art); +extern void _TIE_xt_debug_XSR_DEBUGCAUSE(unsigned art /*inout*/); +extern unsigned _TIE_xt_debug_RSR_ICOUNT(void); +extern void _TIE_xt_debug_WSR_ICOUNT(unsigned art); +extern void _TIE_xt_debug_XSR_ICOUNT(unsigned art /*inout*/); +extern unsigned _TIE_xt_debug_RSR_ICOUNTLEVEL(void); +extern void _TIE_xt_debug_WSR_ICOUNTLEVEL(unsigned art); +extern void _TIE_xt_debug_XSR_ICOUNTLEVEL(unsigned art /*inout*/); +extern unsigned _TIE_xt_debug_RSR_DDR(void); +extern void _TIE_xt_debug_WSR_DDR(unsigned art); +extern void _TIE_xt_debug_XSR_DDR(unsigned art /*inout*/); +#define XT_BREAK _TIE_xt_debug_BREAK +#define XT_BREAK_N _TIE_xt_debug_BREAK_N +#define XT_RSR_DBREAKA0 _TIE_xt_debug_RSR_DBREAKA0 +#define XT_WSR_DBREAKA0 _TIE_xt_debug_WSR_DBREAKA0 +#define XT_XSR_DBREAKA0 _TIE_xt_debug_XSR_DBREAKA0 +#define XT_RSR_DBREAKC0 _TIE_xt_debug_RSR_DBREAKC0 +#define XT_WSR_DBREAKC0 _TIE_xt_debug_WSR_DBREAKC0 +#define XT_XSR_DBREAKC0 _TIE_xt_debug_XSR_DBREAKC0 +#define XT_RSR_IBREAKA0 _TIE_xt_debug_RSR_IBREAKA0 +#define XT_WSR_IBREAKA0 _TIE_xt_debug_WSR_IBREAKA0 +#define XT_XSR_IBREAKA0 _TIE_xt_debug_XSR_IBREAKA0 +#define XT_RSR_IBREAKENABLE _TIE_xt_debug_RSR_IBREAKENABLE +#define XT_WSR_IBREAKENABLE _TIE_xt_debug_WSR_IBREAKENABLE +#define XT_XSR_IBREAKENABLE _TIE_xt_debug_XSR_IBREAKENABLE +#define XT_RSR_DEBUGCAUSE _TIE_xt_debug_RSR_DEBUGCAUSE +#define XT_WSR_DEBUGCAUSE _TIE_xt_debug_WSR_DEBUGCAUSE +#define XT_XSR_DEBUGCAUSE _TIE_xt_debug_XSR_DEBUGCAUSE +#define XT_RSR_ICOUNT _TIE_xt_debug_RSR_ICOUNT +#define XT_WSR_ICOUNT _TIE_xt_debug_WSR_ICOUNT +#define XT_XSR_ICOUNT _TIE_xt_debug_XSR_ICOUNT +#define XT_RSR_ICOUNTLEVEL _TIE_xt_debug_RSR_ICOUNTLEVEL +#define XT_WSR_ICOUNTLEVEL _TIE_xt_debug_WSR_ICOUNTLEVEL +#define XT_XSR_ICOUNTLEVEL _TIE_xt_debug_XSR_ICOUNTLEVEL +#define XT_RSR_DDR _TIE_xt_debug_RSR_DDR +#define XT_WSR_DDR _TIE_xt_debug_WSR_DDR +#define XT_XSR_DDR _TIE_xt_debug_XSR_DDR + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_debug_HEADER */ diff --git a/extra_include/xtensa/tie/xt_density.h b/extra_include/xtensa/tie/xt_density.h index 04ffabbc..6ddf8e41 100644 --- a/extra_include/xtensa/tie/xt_density.h +++ b/extra_include/xtensa/tie/xt_density.h @@ -1,57 +1,57 @@ -/* Definitions for the xt_density TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_density_HEADER -#define _XTENSA_xt_density_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - -#include - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern void _TIE_xt_density_ILL_N(void); -extern void _TIE_xt_density_NOP_N(void); -extern int _TIE_xt_density_L32I_N(const int * p, immediate i); -extern void _TIE_xt_density_S32I_N(int t, int * p, immediate i); -extern int _TIE_xt_density_ADD_N(int s, int t); -extern int _TIE_xt_density_ADDI_N(int s, immediate i); -extern int _TIE_xt_density_MOV_N(int s); -extern int _TIE_xt_density_MOVI_N(immediate i); -#define XT_ILL_N _TIE_xt_density_ILL_N -#define XT_NOP_N _TIE_xt_density_NOP_N -#define XT_L32I_N _TIE_xt_density_L32I_N -#define XT_S32I_N _TIE_xt_density_S32I_N -#define XT_ADD_N _TIE_xt_density_ADD_N -#define XT_ADDI_N _TIE_xt_density_ADDI_N -#define XT_MOV_N _TIE_xt_density_MOV_N -#define XT_MOVI_N _TIE_xt_density_MOVI_N - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_density_HEADER */ +/* Definitions for the xt_density TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_density_HEADER +#define _XTENSA_xt_density_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + +#include + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern void _TIE_xt_density_ILL_N(void); +extern void _TIE_xt_density_NOP_N(void); +extern int _TIE_xt_density_L32I_N(const int * p, immediate i); +extern void _TIE_xt_density_S32I_N(int t, int * p, immediate i); +extern int _TIE_xt_density_ADD_N(int s, int t); +extern int _TIE_xt_density_ADDI_N(int s, immediate i); +extern int _TIE_xt_density_MOV_N(int s); +extern int _TIE_xt_density_MOVI_N(immediate i); +#define XT_ILL_N _TIE_xt_density_ILL_N +#define XT_NOP_N _TIE_xt_density_NOP_N +#define XT_L32I_N _TIE_xt_density_L32I_N +#define XT_S32I_N _TIE_xt_density_S32I_N +#define XT_ADD_N _TIE_xt_density_ADD_N +#define XT_ADDI_N _TIE_xt_density_ADDI_N +#define XT_MOV_N _TIE_xt_density_MOV_N +#define XT_MOVI_N _TIE_xt_density_MOVI_N + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_density_HEADER */ diff --git a/extra_include/xtensa/tie/xt_exceptions.h b/extra_include/xtensa/tie/xt_exceptions.h index f632a4c6..46899d42 100644 --- a/extra_include/xtensa/tie/xt_exceptions.h +++ b/extra_include/xtensa/tie/xt_exceptions.h @@ -1,46 +1,46 @@ -/* Definitions for the xt_exceptions TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_exceptions_HEADER -#define _XTENSA_xt_exceptions_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern void _TIE_xt_exceptions_EXCW(void); -extern void _TIE_xt_exceptions_SYSCALL(void); -extern void _TIE_xt_exceptions_SIMCALL(void); -#define XT_EXCW _TIE_xt_exceptions_EXCW -#define XT_SYSCALL _TIE_xt_exceptions_SYSCALL -#define XT_SIMCALL _TIE_xt_exceptions_SIMCALL - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_exceptions_HEADER */ +/* Definitions for the xt_exceptions TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_exceptions_HEADER +#define _XTENSA_xt_exceptions_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern void _TIE_xt_exceptions_EXCW(void); +extern void _TIE_xt_exceptions_SYSCALL(void); +extern void _TIE_xt_exceptions_SIMCALL(void); +#define XT_EXCW _TIE_xt_exceptions_EXCW +#define XT_SYSCALL _TIE_xt_exceptions_SYSCALL +#define XT_SIMCALL _TIE_xt_exceptions_SIMCALL + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_exceptions_HEADER */ diff --git a/extra_include/xtensa/tie/xt_externalregisters.h b/extra_include/xtensa/tie/xt_externalregisters.h index 51913d52..2bc2d88b 100644 --- a/extra_include/xtensa/tie/xt_externalregisters.h +++ b/extra_include/xtensa/tie/xt_externalregisters.h @@ -1,44 +1,44 @@ -/* Definitions for the xt_externalregisters TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_externalregisters_HEADER -#define _XTENSA_xt_externalregisters_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern void _TIE_xt_externalregisters_RER(void); -extern void _TIE_xt_externalregisters_WER(void); -#define XT_RER _TIE_xt_externalregisters_RER -#define XT_WER _TIE_xt_externalregisters_WER - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_externalregisters_HEADER */ +/* Definitions for the xt_externalregisters TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_externalregisters_HEADER +#define _XTENSA_xt_externalregisters_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern void _TIE_xt_externalregisters_RER(void); +extern void _TIE_xt_externalregisters_WER(void); +#define XT_RER _TIE_xt_externalregisters_RER +#define XT_WER _TIE_xt_externalregisters_WER + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_externalregisters_HEADER */ diff --git a/extra_include/xtensa/tie/xt_interrupt.h b/extra_include/xtensa/tie/xt_interrupt.h index f6ffb6ea..f5c60346 100644 --- a/extra_include/xtensa/tie/xt_interrupt.h +++ b/extra_include/xtensa/tie/xt_interrupt.h @@ -1,55 +1,55 @@ -/* Definitions for the xt_interrupt TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_interrupt_HEADER -#define _XTENSA_xt_interrupt_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - -#include - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern void _TIE_xt_interrupt_WAITI(immediate s); -extern unsigned _TIE_xt_interrupt_RSR_INTERRUPT(void); -extern void _TIE_xt_interrupt_WSR_INTSET(unsigned art); -extern void _TIE_xt_interrupt_WSR_INTCLEAR(unsigned art); -extern unsigned _TIE_xt_interrupt_RSR_INTENABLE(void); -extern void _TIE_xt_interrupt_WSR_INTENABLE(unsigned art); -extern void _TIE_xt_interrupt_XSR_INTENABLE(unsigned art /*inout*/); -#define XT_WAITI _TIE_xt_interrupt_WAITI -#define XT_RSR_INTERRUPT _TIE_xt_interrupt_RSR_INTERRUPT -#define XT_WSR_INTSET _TIE_xt_interrupt_WSR_INTSET -#define XT_WSR_INTCLEAR _TIE_xt_interrupt_WSR_INTCLEAR -#define XT_RSR_INTENABLE _TIE_xt_interrupt_RSR_INTENABLE -#define XT_WSR_INTENABLE _TIE_xt_interrupt_WSR_INTENABLE -#define XT_XSR_INTENABLE _TIE_xt_interrupt_XSR_INTENABLE - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_interrupt_HEADER */ +/* Definitions for the xt_interrupt TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_interrupt_HEADER +#define _XTENSA_xt_interrupt_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + +#include + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern void _TIE_xt_interrupt_WAITI(immediate s); +extern unsigned _TIE_xt_interrupt_RSR_INTERRUPT(void); +extern void _TIE_xt_interrupt_WSR_INTSET(unsigned art); +extern void _TIE_xt_interrupt_WSR_INTCLEAR(unsigned art); +extern unsigned _TIE_xt_interrupt_RSR_INTENABLE(void); +extern void _TIE_xt_interrupt_WSR_INTENABLE(unsigned art); +extern void _TIE_xt_interrupt_XSR_INTENABLE(unsigned art /*inout*/); +#define XT_WAITI _TIE_xt_interrupt_WAITI +#define XT_RSR_INTERRUPT _TIE_xt_interrupt_RSR_INTERRUPT +#define XT_WSR_INTSET _TIE_xt_interrupt_WSR_INTSET +#define XT_WSR_INTCLEAR _TIE_xt_interrupt_WSR_INTCLEAR +#define XT_RSR_INTENABLE _TIE_xt_interrupt_RSR_INTENABLE +#define XT_WSR_INTENABLE _TIE_xt_interrupt_WSR_INTENABLE +#define XT_XSR_INTENABLE _TIE_xt_interrupt_XSR_INTENABLE + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_interrupt_HEADER */ diff --git a/extra_include/xtensa/tie/xt_misc.h b/extra_include/xtensa/tie/xt_misc.h index 2d8fcf0f..36d701f7 100644 --- a/extra_include/xtensa/tie/xt_misc.h +++ b/extra_include/xtensa/tie/xt_misc.h @@ -1,45 +1,45 @@ -/* Definitions for the xt_misc TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_misc_HEADER -#define _XTENSA_xt_misc_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - -#include - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern int _TIE_xt_misc_NSA(int s); -extern unsigned _TIE_xt_misc_NSAU(unsigned s); -#define XT_NSA _TIE_xt_misc_NSA -#define XT_NSAU _TIE_xt_misc_NSAU - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_misc_HEADER */ +/* Definitions for the xt_misc TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_misc_HEADER +#define _XTENSA_xt_misc_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + +#include + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern int _TIE_xt_misc_NSA(int s); +extern unsigned _TIE_xt_misc_NSAU(unsigned s); +#define XT_NSA _TIE_xt_misc_NSA +#define XT_NSAU _TIE_xt_misc_NSAU + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_misc_HEADER */ diff --git a/extra_include/xtensa/tie/xt_mmu.h b/extra_include/xtensa/tie/xt_mmu.h index 4ecd59e3..0290b30b 100644 --- a/extra_include/xtensa/tie/xt_mmu.h +++ b/extra_include/xtensa/tie/xt_mmu.h @@ -1,61 +1,61 @@ -/* Definitions for the xt_mmu TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_mmu_HEADER -#define _XTENSA_xt_mmu_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - -#include - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern void _TIE_xt_mmu_IDTLB(unsigned ars); -extern unsigned _TIE_xt_mmu_RDTLB1(unsigned ars); -extern unsigned _TIE_xt_mmu_RDTLB0(unsigned ars); -extern unsigned _TIE_xt_mmu_PDTLB(unsigned ars); -extern void _TIE_xt_mmu_WDTLB(unsigned art, unsigned ars); -extern void _TIE_xt_mmu_IITLB(unsigned ars); -extern unsigned _TIE_xt_mmu_RITLB1(unsigned ars); -extern unsigned _TIE_xt_mmu_RITLB0(unsigned ars); -extern unsigned _TIE_xt_mmu_PITLB(unsigned ars); -extern void _TIE_xt_mmu_WITLB(unsigned art, unsigned ars); -#define XT_IDTLB _TIE_xt_mmu_IDTLB -#define XT_RDTLB1 _TIE_xt_mmu_RDTLB1 -#define XT_RDTLB0 _TIE_xt_mmu_RDTLB0 -#define XT_PDTLB _TIE_xt_mmu_PDTLB -#define XT_WDTLB _TIE_xt_mmu_WDTLB -#define XT_IITLB _TIE_xt_mmu_IITLB -#define XT_RITLB1 _TIE_xt_mmu_RITLB1 -#define XT_RITLB0 _TIE_xt_mmu_RITLB0 -#define XT_PITLB _TIE_xt_mmu_PITLB -#define XT_WITLB _TIE_xt_mmu_WITLB - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_mmu_HEADER */ +/* Definitions for the xt_mmu TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_mmu_HEADER +#define _XTENSA_xt_mmu_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + +#include + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern void _TIE_xt_mmu_IDTLB(unsigned ars); +extern unsigned _TIE_xt_mmu_RDTLB1(unsigned ars); +extern unsigned _TIE_xt_mmu_RDTLB0(unsigned ars); +extern unsigned _TIE_xt_mmu_PDTLB(unsigned ars); +extern void _TIE_xt_mmu_WDTLB(unsigned art, unsigned ars); +extern void _TIE_xt_mmu_IITLB(unsigned ars); +extern unsigned _TIE_xt_mmu_RITLB1(unsigned ars); +extern unsigned _TIE_xt_mmu_RITLB0(unsigned ars); +extern unsigned _TIE_xt_mmu_PITLB(unsigned ars); +extern void _TIE_xt_mmu_WITLB(unsigned art, unsigned ars); +#define XT_IDTLB _TIE_xt_mmu_IDTLB +#define XT_RDTLB1 _TIE_xt_mmu_RDTLB1 +#define XT_RDTLB0 _TIE_xt_mmu_RDTLB0 +#define XT_PDTLB _TIE_xt_mmu_PDTLB +#define XT_WDTLB _TIE_xt_mmu_WDTLB +#define XT_IITLB _TIE_xt_mmu_IITLB +#define XT_RITLB1 _TIE_xt_mmu_RITLB1 +#define XT_RITLB0 _TIE_xt_mmu_RITLB0 +#define XT_PITLB _TIE_xt_mmu_PITLB +#define XT_WITLB _TIE_xt_mmu_WITLB + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_mmu_HEADER */ diff --git a/extra_include/xtensa/tie/xt_mul.h b/extra_include/xtensa/tie/xt_mul.h index 42599f2a..5a033910 100644 --- a/extra_include/xtensa/tie/xt_mul.h +++ b/extra_include/xtensa/tie/xt_mul.h @@ -1,47 +1,47 @@ -/* Definitions for the xt_mul TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_mul_HEADER -#define _XTENSA_xt_mul_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - -#include - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern int _TIE_xt_mul_MUL16S(short s, short t); -extern unsigned _TIE_xt_mul_MUL16U(unsigned short s, unsigned short t); -extern int _TIE_xt_mul_MULL(int s, int t); -#define XT_MUL16S _TIE_xt_mul_MUL16S -#define XT_MUL16U _TIE_xt_mul_MUL16U -#define XT_MULL _TIE_xt_mul_MULL - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_mul_HEADER */ +/* Definitions for the xt_mul TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_mul_HEADER +#define _XTENSA_xt_mul_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + +#include + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern int _TIE_xt_mul_MUL16S(short s, short t); +extern unsigned _TIE_xt_mul_MUL16U(unsigned short s, unsigned short t); +extern int _TIE_xt_mul_MULL(int s, int t); +#define XT_MUL16S _TIE_xt_mul_MUL16S +#define XT_MUL16U _TIE_xt_mul_MUL16U +#define XT_MULL _TIE_xt_mul_MULL + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_mul_HEADER */ diff --git a/extra_include/xtensa/tie/xt_timer.h b/extra_include/xtensa/tie/xt_timer.h index a30d3fb5..aefe343c 100644 --- a/extra_include/xtensa/tie/xt_timer.h +++ b/extra_include/xtensa/tie/xt_timer.h @@ -1,53 +1,53 @@ -/* Definitions for the xt_timer TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_timer_HEADER -#define _XTENSA_xt_timer_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - -#include - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern unsigned _TIE_xt_timer_RSR_CCOUNT(void); -extern void _TIE_xt_timer_WSR_CCOUNT(unsigned art); -extern void _TIE_xt_timer_XSR_CCOUNT(unsigned art /*inout*/); -extern unsigned _TIE_xt_timer_RSR_CCOMPARE0(void); -extern void _TIE_xt_timer_WSR_CCOMPARE0(unsigned art); -extern void _TIE_xt_timer_XSR_CCOMPARE0(unsigned art /*inout*/); -#define XT_RSR_CCOUNT _TIE_xt_timer_RSR_CCOUNT -#define XT_WSR_CCOUNT _TIE_xt_timer_WSR_CCOUNT -#define XT_XSR_CCOUNT _TIE_xt_timer_XSR_CCOUNT -#define XT_RSR_CCOMPARE0 _TIE_xt_timer_RSR_CCOMPARE0 -#define XT_WSR_CCOMPARE0 _TIE_xt_timer_WSR_CCOMPARE0 -#define XT_XSR_CCOMPARE0 _TIE_xt_timer_XSR_CCOMPARE0 - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_timer_HEADER */ +/* Definitions for the xt_timer TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_timer_HEADER +#define _XTENSA_xt_timer_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + +#include + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern unsigned _TIE_xt_timer_RSR_CCOUNT(void); +extern void _TIE_xt_timer_WSR_CCOUNT(unsigned art); +extern void _TIE_xt_timer_XSR_CCOUNT(unsigned art /*inout*/); +extern unsigned _TIE_xt_timer_RSR_CCOMPARE0(void); +extern void _TIE_xt_timer_WSR_CCOMPARE0(unsigned art); +extern void _TIE_xt_timer_XSR_CCOMPARE0(unsigned art /*inout*/); +#define XT_RSR_CCOUNT _TIE_xt_timer_RSR_CCOUNT +#define XT_WSR_CCOUNT _TIE_xt_timer_WSR_CCOUNT +#define XT_XSR_CCOUNT _TIE_xt_timer_XSR_CCOUNT +#define XT_RSR_CCOMPARE0 _TIE_xt_timer_RSR_CCOMPARE0 +#define XT_WSR_CCOMPARE0 _TIE_xt_timer_WSR_CCOMPARE0 +#define XT_XSR_CCOMPARE0 _TIE_xt_timer_XSR_CCOMPARE0 + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_timer_HEADER */ diff --git a/extra_include/xtensa/tie/xt_trace.h b/extra_include/xtensa/tie/xt_trace.h index 9f26438a..0d01f91d 100644 --- a/extra_include/xtensa/tie/xt_trace.h +++ b/extra_include/xtensa/tie/xt_trace.h @@ -1,43 +1,43 @@ -/* Definitions for the xt_trace TIE package */ - -/* - * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. - * These coded instructions, statements, and computer programs are the - * copyrighted works and confidential proprietary information of Tensilica Inc. - * They may not be modified, copied, reproduced, distributed, or disclosed to - * third parties in any manner, medium, or form, in whole or in part, without - * the prior written consent of Tensilica Inc. - */ - -/* Do not modify. This is automatically generated.*/ - -#ifndef _XTENSA_xt_trace_HEADER -#define _XTENSA_xt_trace_HEADER - -#ifdef __XTENSA__ -#ifdef __XCC__ - -#include - -/* - * The following prototypes describe intrinsic functions - * corresponding to TIE instructions. Some TIE instructions - * may produce multiple results (designated as "out" operands - * in the iclass section) or may have operands used as both - * inputs and outputs (designated as "inout"). However, the C - * and C++ languages do not provide syntax that can express - * the in/out/inout constraints of TIE intrinsics. - * Nevertheless, the compiler understands these constraints - * and will check that the intrinsic functions are used - * correctly. To improve the readability of these prototypes, - * the "out" and "inout" parameters are marked accordingly - * with comments. - */ - -extern void _TIE_xt_trace_WSR_MMID(unsigned art); -#define XT_WSR_MMID _TIE_xt_trace_WSR_MMID - -#endif /* __XCC__ */ - -#endif /* __XTENSA__ */ -#endif /* !_XTENSA_xt_trace_HEADER */ +/* Definitions for the xt_trace TIE package */ + +/* + * Customer ID=7011; Build=0x2b6f6; Copyright (c) 2004 by Tensilica Inc. ALL RIGHTS RESERVED. + * These coded instructions, statements, and computer programs are the + * copyrighted works and confidential proprietary information of Tensilica Inc. + * They may not be modified, copied, reproduced, distributed, or disclosed to + * third parties in any manner, medium, or form, in whole or in part, without + * the prior written consent of Tensilica Inc. + */ + +/* Do not modify. This is automatically generated.*/ + +#ifndef _XTENSA_xt_trace_HEADER +#define _XTENSA_xt_trace_HEADER + +#ifdef __XTENSA__ +#ifdef __XCC__ + +#include + +/* + * The following prototypes describe intrinsic functions + * corresponding to TIE instructions. Some TIE instructions + * may produce multiple results (designated as "out" operands + * in the iclass section) or may have operands used as both + * inputs and outputs (designated as "inout"). However, the C + * and C++ languages do not provide syntax that can express + * the in/out/inout constraints of TIE intrinsics. + * Nevertheless, the compiler understands these constraints + * and will check that the intrinsic functions are used + * correctly. To improve the readability of these prototypes, + * the "out" and "inout" parameters are marked accordingly + * with comments. + */ + +extern void _TIE_xt_trace_WSR_MMID(unsigned art); +#define XT_WSR_MMID _TIE_xt_trace_WSR_MMID + +#endif /* __XCC__ */ + +#endif /* __XTENSA__ */ +#endif /* !_XTENSA_xt_trace_HEADER */ diff --git a/extra_include/xtensa/xtensa-libdb-macros.h b/extra_include/xtensa/xtensa-libdb-macros.h index 7f5f8f33..b52f2d76 100644 --- a/extra_include/xtensa/xtensa-libdb-macros.h +++ b/extra_include/xtensa/xtensa-libdb-macros.h @@ -1,165 +1,165 @@ -/* - * xtensa-libdb-macros.h - */ - -/* $Id: //depot/rel/Boreal/Xtensa/Software/libdb/xtensa-libdb-macros.h#2 $ */ - -/* Copyright (c) 2004-2008 Tensilica Inc. - - 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 __H_LIBDB_MACROS -#define __H_LIBDB_MACROS - -/* - * This header file provides macros used to construct, identify and use - * "target numbers" that are assigned to various types of Xtensa processor - * registers and states. These target numbers are used by GDB in the remote - * protocol, and are thus used by all GDB debugger agents (targets). - * They are also used in ELF debugger information sections (stabs, dwarf, etc). - * - * These macros are separated from xtensa-libdb.h because they are needed - * by certain debugger agents that do not use or have access to libdb, - * e.g. the OCD daemon, RedBoot, XMON, etc. - * - * For the time being, for compatibility with certain 3rd party debugger - * software vendors, target numbers are limited to 16 bits. It is - * conceivable that this will be extended in the future to 32 bits. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef uint32 - #define uint32 unsigned int -#endif -#ifndef int32 - #define int32 int -#endif - - -/* - * Macros to form register "target numbers" for various standard registers/states: - */ -#define XTENSA_DBREGN_INVALID -1 /* not a valid target number */ -#define XTENSA_DBREGN_A(n) (0x0000+(n)) /* address registers a0..a15 */ -#define XTENSA_DBREGN_B(n) (0x0010+(n)) /* boolean bits b0..b15 */ -#define XTENSA_DBREGN_PC 0x0020 /* program counter */ - /* 0x0021 RESERVED for use by Tensilica */ -#define XTENSA_DBREGN_BO(n) (0x0022+(n)) /* boolean octuple-bits bo0..bo1 */ -#define XTENSA_DBREGN_BQ(n) (0x0024+(n)) /* boolean quadruple-bits bq0..bq3 */ -#define XTENSA_DBREGN_BD(n) (0x0028+(n)) /* boolean double-bits bd0..bd7 */ -#define XTENSA_DBREGN_F(n) (0x0030+(n)) /* floating point registers f0..f15 */ -#define XTENSA_DBREGN_VEC(n) (0x0040+(n)) /* Vectra vec regs v0..v15 */ -#define XTENSA_DBREGN_VSEL(n) (0x0050+(n)) /* Vectra sel s0..s3 (V1) ..s7 (V2) */ -#define XTENSA_DBREGN_VALIGN(n) (0x0058+(n)) /* Vectra valign regs u0..u3 */ -#define XTENSA_DBREGN_VCOEFF(n) (0x005C+(n)) /* Vectra I vcoeff regs c0..c1 */ - /* 0x005E..0x005F RESERVED for use by Tensilica */ -#define XTENSA_DBREGN_AEP(n) (0x0060+(n)) /* HiFi2 Audio Engine regs aep0..aep7 */ -#define XTENSA_DBREGN_AEQ(n) (0x0068+(n)) /* HiFi2 Audio Engine regs aeq0..aeq3 */ - /* 0x006C..0x006F RESERVED for use by Tensilica */ -#define XTENSA_DBREGN_DF(n) (0x0070+(n)) /* double floating point registers df0..df15 */ - /* 0x0080..0x00FF RESERVED for use by Tensilica */ -#define XTENSA_DBREGN_AR(n) (0x0100+(n)) /* physical address regs ar0..ar63 - (note: only with window option) */ - /* 0x0140..0x01FF RESERVED for use by Tensilica */ -#define XTENSA_DBREGN_SREG(n) (0x0200+(n)) /* special registers 0..255 (core) */ -#define XTENSA_DBREGN_BR XTENSA_DBREGN_SREG(0x04) /* all 16 boolean bits, BR */ -#define XTENSA_DBREGN_MR(n) XTENSA_DBREGN_SREG(0x20+(n)) /* MAC16 registers m0..m3 */ -#define XTENSA_DBREGN_UREG(n) (0x0300+(n)) /* user registers 0..255 (TIE) */ - /* 0x0400..0x0FFF RESERVED for use by Tensilica */ - /* 0x1000..0x1FFF user-defined regfiles */ - /* 0x2000..0xEFFF other states (and regfiles) */ -#define XTENSA_DBREGN_DBAGENT(n) (0xF000+(n)) /* non-processor "registers" 0..4095 for - 3rd-party debugger agent defined use */ - /* > 0xFFFF (32-bit) RESERVED for use by Tensilica */ -/*#define XTENSA_DBREGN_CONTEXT(n) (0x02000000+((n)<<20))*/ /* add this macro's value to a target - number to identify a specific context 0..31 - for context-replicated registers */ -#define XTENSA_DBREGN_MASK 0xFFFF /* mask of valid target_number bits */ -#define XTENSA_DBREGN_WRITE_SIDE 0x04000000 /* flag to request write half of a register - split into distinct read and write entries - with the same target number (currently only - valid in a couple of libdb API functions; - see xtensa-libdb.h for details) */ - -/* - * Macros to identify specific ranges of target numbers (formed above): - * NOTE: any context number (or other upper 12 bits) are considered - * modifiers and are thus stripped out for identification purposes. - */ -#define XTENSA_DBREGN_IS_VALID(tn) (((tn) & ~0xFFFF) == 0) /* just tests it's 16-bit unsigned */ -#define XTENSA_DBREGN_IS_A(tn) (((tn) & 0xFFF0)==0x0000) /* is a0..a15 */ -#define XTENSA_DBREGN_IS_B(tn) (((tn) & 0xFFF0)==0x0010) /* is b0..b15 */ -#define XTENSA_DBREGN_IS_PC(tn) (((tn) & 0xFFFF)==0x0020) /* is program counter */ -#define XTENSA_DBREGN_IS_BO(tn) (((tn) & 0xFFFE)==0x0022) /* is bo0..bo1 */ -#define XTENSA_DBREGN_IS_BQ(tn) (((tn) & 0xFFFC)==0x0024) /* is bq0..bq3 */ -#define XTENSA_DBREGN_IS_BD(tn) (((tn) & 0xFFF8)==0x0028) /* is bd0..bd7 */ -#define XTENSA_DBREGN_IS_F(tn) (((tn) & 0xFFF0)==0x0030) /* is f0..f15 */ -#define XTENSA_DBREGN_IS_VEC(tn) (((tn) & 0xFFF0)==0x0040) /* is v0..v15 */ -#define XTENSA_DBREGN_IS_VSEL(tn) (((tn) & 0xFFF8)==0x0050) /* is s0..s7 (s0..s3 in V1) */ -#define XTENSA_DBREGN_IS_VALIGN(tn) (((tn) & 0xFFFC)==0x0058) /* is u0..u3 */ -#define XTENSA_DBREGN_IS_VCOEFF(tn) (((tn) & 0xFFFE)==0x005C) /* is c0..c1 */ -#define XTENSA_DBREGN_IS_AEP(tn) (((tn) & 0xFFF8)==0x0060) /* is aep0..aep7 */ -#define XTENSA_DBREGN_IS_AEQ(tn) (((tn) & 0xFFFC)==0x0068) /* is aeq0..aeq3 */ -#define XTENSA_DBREGN_IS_DF(tn) (((tn) & 0xFFF0)==0x0070) /* is df0..df15 */ -#define XTENSA_DBREGN_IS_AR(tn) (((tn) & 0xFFC0)==0x0100) /* is ar0..ar63 */ -#define XTENSA_DBREGN_IS_SREG(tn) (((tn) & 0xFF00)==0x0200) /* is special register */ -#define XTENSA_DBREGN_IS_BR(tn) (((tn) & 0xFFFF)==XTENSA_DBREGN_SREG(0x04)) /* is BR */ -#define XTENSA_DBREGN_IS_MR(tn) (((tn) & 0xFFFC)==XTENSA_DBREGN_SREG(0x20)) /* m0..m3 */ -#define XTENSA_DBREGN_IS_UREG(tn) (((tn) & 0xFF00)==0x0300) /* is user register */ -#define XTENSA_DBREGN_IS_DBAGENT(tn) (((tn) & 0xF000)==0xF000) /* is non-processor */ -/*#define XTENSA_DBREGN_IS_CONTEXT(tn) (((tn) & 0x02000000) != 0)*/ /* specifies context # */ - -/* - * Macros to extract register index from a register "target number" - * when a specific range has been identified using one of the _IS_ macros above. - * These macros only return a useful value if the corresponding _IS_ macro returns true. - */ -#define XTENSA_DBREGN_A_INDEX(tn) ((tn) & 0x0F) /* 0..15 for a0..a15 */ -#define XTENSA_DBREGN_B_INDEX(tn) ((tn) & 0x0F) /* 0..15 for b0..b15 */ -#define XTENSA_DBREGN_BO_INDEX(tn) ((tn) & 0x01) /* 0..1 for bo0..bo1 */ -#define XTENSA_DBREGN_BQ_INDEX(tn) ((tn) & 0x03) /* 0..3 for bq0..bq3 */ -#define XTENSA_DBREGN_BD_INDEX(tn) ((tn) & 0x07) /* 0..7 for bd0..bd7 */ -#define XTENSA_DBREGN_F_INDEX(tn) ((tn) & 0x0F) /* 0..15 for f0..f15 */ -#define XTENSA_DBREGN_VEC_INDEX(tn) ((tn) & 0x0F) /* 0..15 for v0..v15 */ -#define XTENSA_DBREGN_VSEL_INDEX(tn) ((tn) & 0x07) /* 0..7 for s0..s7 */ -#define XTENSA_DBREGN_VALIGN_INDEX(tn) ((tn) & 0x03) /* 0..3 for u0..u3 */ -#define XTENSA_DBREGN_VCOEFF_INDEX(tn) ((tn) & 0x01) /* 0..1 for c0..c1 */ -#define XTENSA_DBREGN_AEP_INDEX(tn) ((tn) & 0x07) /* 0..7 for aep0..aep7 */ -#define XTENSA_DBREGN_AEQ_INDEX(tn) ((tn) & 0x03) /* 0..3 for aeq0..aeq3 */ -#define XTENSA_DBREGN_DF_INDEX(tn) ((tn) & 0x0F) /* 0..15 for df0..df15 */ -#define XTENSA_DBREGN_AR_INDEX(tn) ((tn) & 0x3F) /* 0..63 for ar0..ar63 */ -#define XTENSA_DBREGN_SREG_INDEX(tn) ((tn) & 0xFF) /* 0..255 for special registers */ -#define XTENSA_DBREGN_MR_INDEX(tn) ((tn) & 0x03) /* 0..3 for m0..m3 */ -#define XTENSA_DBREGN_UREG_INDEX(tn) ((tn) & 0xFF) /* 0..255 for user registers */ -#define XTENSA_DBREGN_DBAGENT_INDEX(tn) ((tn) & 0xFFF) /* 0..4095 for non-processor */ -/*#define XTENSA_DBREGN_CONTEXT_INDEX(tn) (((tn) >> 20) & 0x1F)*/ /* 0..31 context numbers */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __H_LIBDB_MACROS */ - +/* + * xtensa-libdb-macros.h + */ + +/* $Id: //depot/rel/Boreal/Xtensa/Software/libdb/xtensa-libdb-macros.h#2 $ */ + +/* Copyright (c) 2004-2008 Tensilica Inc. + + 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 __H_LIBDB_MACROS +#define __H_LIBDB_MACROS + +/* + * This header file provides macros used to construct, identify and use + * "target numbers" that are assigned to various types of Xtensa processor + * registers and states. These target numbers are used by GDB in the remote + * protocol, and are thus used by all GDB debugger agents (targets). + * They are also used in ELF debugger information sections (stabs, dwarf, etc). + * + * These macros are separated from xtensa-libdb.h because they are needed + * by certain debugger agents that do not use or have access to libdb, + * e.g. the OCD daemon, RedBoot, XMON, etc. + * + * For the time being, for compatibility with certain 3rd party debugger + * software vendors, target numbers are limited to 16 bits. It is + * conceivable that this will be extended in the future to 32 bits. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef uint32 + #define uint32 unsigned int +#endif +#ifndef int32 + #define int32 int +#endif + + +/* + * Macros to form register "target numbers" for various standard registers/states: + */ +#define XTENSA_DBREGN_INVALID -1 /* not a valid target number */ +#define XTENSA_DBREGN_A(n) (0x0000+(n)) /* address registers a0..a15 */ +#define XTENSA_DBREGN_B(n) (0x0010+(n)) /* boolean bits b0..b15 */ +#define XTENSA_DBREGN_PC 0x0020 /* program counter */ + /* 0x0021 RESERVED for use by Tensilica */ +#define XTENSA_DBREGN_BO(n) (0x0022+(n)) /* boolean octuple-bits bo0..bo1 */ +#define XTENSA_DBREGN_BQ(n) (0x0024+(n)) /* boolean quadruple-bits bq0..bq3 */ +#define XTENSA_DBREGN_BD(n) (0x0028+(n)) /* boolean double-bits bd0..bd7 */ +#define XTENSA_DBREGN_F(n) (0x0030+(n)) /* floating point registers f0..f15 */ +#define XTENSA_DBREGN_VEC(n) (0x0040+(n)) /* Vectra vec regs v0..v15 */ +#define XTENSA_DBREGN_VSEL(n) (0x0050+(n)) /* Vectra sel s0..s3 (V1) ..s7 (V2) */ +#define XTENSA_DBREGN_VALIGN(n) (0x0058+(n)) /* Vectra valign regs u0..u3 */ +#define XTENSA_DBREGN_VCOEFF(n) (0x005C+(n)) /* Vectra I vcoeff regs c0..c1 */ + /* 0x005E..0x005F RESERVED for use by Tensilica */ +#define XTENSA_DBREGN_AEP(n) (0x0060+(n)) /* HiFi2 Audio Engine regs aep0..aep7 */ +#define XTENSA_DBREGN_AEQ(n) (0x0068+(n)) /* HiFi2 Audio Engine regs aeq0..aeq3 */ + /* 0x006C..0x006F RESERVED for use by Tensilica */ +#define XTENSA_DBREGN_DF(n) (0x0070+(n)) /* double floating point registers df0..df15 */ + /* 0x0080..0x00FF RESERVED for use by Tensilica */ +#define XTENSA_DBREGN_AR(n) (0x0100+(n)) /* physical address regs ar0..ar63 + (note: only with window option) */ + /* 0x0140..0x01FF RESERVED for use by Tensilica */ +#define XTENSA_DBREGN_SREG(n) (0x0200+(n)) /* special registers 0..255 (core) */ +#define XTENSA_DBREGN_BR XTENSA_DBREGN_SREG(0x04) /* all 16 boolean bits, BR */ +#define XTENSA_DBREGN_MR(n) XTENSA_DBREGN_SREG(0x20+(n)) /* MAC16 registers m0..m3 */ +#define XTENSA_DBREGN_UREG(n) (0x0300+(n)) /* user registers 0..255 (TIE) */ + /* 0x0400..0x0FFF RESERVED for use by Tensilica */ + /* 0x1000..0x1FFF user-defined regfiles */ + /* 0x2000..0xEFFF other states (and regfiles) */ +#define XTENSA_DBREGN_DBAGENT(n) (0xF000+(n)) /* non-processor "registers" 0..4095 for + 3rd-party debugger agent defined use */ + /* > 0xFFFF (32-bit) RESERVED for use by Tensilica */ +/*#define XTENSA_DBREGN_CONTEXT(n) (0x02000000+((n)<<20))*/ /* add this macro's value to a target + number to identify a specific context 0..31 + for context-replicated registers */ +#define XTENSA_DBREGN_MASK 0xFFFF /* mask of valid target_number bits */ +#define XTENSA_DBREGN_WRITE_SIDE 0x04000000 /* flag to request write half of a register + split into distinct read and write entries + with the same target number (currently only + valid in a couple of libdb API functions; + see xtensa-libdb.h for details) */ + +/* + * Macros to identify specific ranges of target numbers (formed above): + * NOTE: any context number (or other upper 12 bits) are considered + * modifiers and are thus stripped out for identification purposes. + */ +#define XTENSA_DBREGN_IS_VALID(tn) (((tn) & ~0xFFFF) == 0) /* just tests it's 16-bit unsigned */ +#define XTENSA_DBREGN_IS_A(tn) (((tn) & 0xFFF0)==0x0000) /* is a0..a15 */ +#define XTENSA_DBREGN_IS_B(tn) (((tn) & 0xFFF0)==0x0010) /* is b0..b15 */ +#define XTENSA_DBREGN_IS_PC(tn) (((tn) & 0xFFFF)==0x0020) /* is program counter */ +#define XTENSA_DBREGN_IS_BO(tn) (((tn) & 0xFFFE)==0x0022) /* is bo0..bo1 */ +#define XTENSA_DBREGN_IS_BQ(tn) (((tn) & 0xFFFC)==0x0024) /* is bq0..bq3 */ +#define XTENSA_DBREGN_IS_BD(tn) (((tn) & 0xFFF8)==0x0028) /* is bd0..bd7 */ +#define XTENSA_DBREGN_IS_F(tn) (((tn) & 0xFFF0)==0x0030) /* is f0..f15 */ +#define XTENSA_DBREGN_IS_VEC(tn) (((tn) & 0xFFF0)==0x0040) /* is v0..v15 */ +#define XTENSA_DBREGN_IS_VSEL(tn) (((tn) & 0xFFF8)==0x0050) /* is s0..s7 (s0..s3 in V1) */ +#define XTENSA_DBREGN_IS_VALIGN(tn) (((tn) & 0xFFFC)==0x0058) /* is u0..u3 */ +#define XTENSA_DBREGN_IS_VCOEFF(tn) (((tn) & 0xFFFE)==0x005C) /* is c0..c1 */ +#define XTENSA_DBREGN_IS_AEP(tn) (((tn) & 0xFFF8)==0x0060) /* is aep0..aep7 */ +#define XTENSA_DBREGN_IS_AEQ(tn) (((tn) & 0xFFFC)==0x0068) /* is aeq0..aeq3 */ +#define XTENSA_DBREGN_IS_DF(tn) (((tn) & 0xFFF0)==0x0070) /* is df0..df15 */ +#define XTENSA_DBREGN_IS_AR(tn) (((tn) & 0xFFC0)==0x0100) /* is ar0..ar63 */ +#define XTENSA_DBREGN_IS_SREG(tn) (((tn) & 0xFF00)==0x0200) /* is special register */ +#define XTENSA_DBREGN_IS_BR(tn) (((tn) & 0xFFFF)==XTENSA_DBREGN_SREG(0x04)) /* is BR */ +#define XTENSA_DBREGN_IS_MR(tn) (((tn) & 0xFFFC)==XTENSA_DBREGN_SREG(0x20)) /* m0..m3 */ +#define XTENSA_DBREGN_IS_UREG(tn) (((tn) & 0xFF00)==0x0300) /* is user register */ +#define XTENSA_DBREGN_IS_DBAGENT(tn) (((tn) & 0xF000)==0xF000) /* is non-processor */ +/*#define XTENSA_DBREGN_IS_CONTEXT(tn) (((tn) & 0x02000000) != 0)*/ /* specifies context # */ + +/* + * Macros to extract register index from a register "target number" + * when a specific range has been identified using one of the _IS_ macros above. + * These macros only return a useful value if the corresponding _IS_ macro returns true. + */ +#define XTENSA_DBREGN_A_INDEX(tn) ((tn) & 0x0F) /* 0..15 for a0..a15 */ +#define XTENSA_DBREGN_B_INDEX(tn) ((tn) & 0x0F) /* 0..15 for b0..b15 */ +#define XTENSA_DBREGN_BO_INDEX(tn) ((tn) & 0x01) /* 0..1 for bo0..bo1 */ +#define XTENSA_DBREGN_BQ_INDEX(tn) ((tn) & 0x03) /* 0..3 for bq0..bq3 */ +#define XTENSA_DBREGN_BD_INDEX(tn) ((tn) & 0x07) /* 0..7 for bd0..bd7 */ +#define XTENSA_DBREGN_F_INDEX(tn) ((tn) & 0x0F) /* 0..15 for f0..f15 */ +#define XTENSA_DBREGN_VEC_INDEX(tn) ((tn) & 0x0F) /* 0..15 for v0..v15 */ +#define XTENSA_DBREGN_VSEL_INDEX(tn) ((tn) & 0x07) /* 0..7 for s0..s7 */ +#define XTENSA_DBREGN_VALIGN_INDEX(tn) ((tn) & 0x03) /* 0..3 for u0..u3 */ +#define XTENSA_DBREGN_VCOEFF_INDEX(tn) ((tn) & 0x01) /* 0..1 for c0..c1 */ +#define XTENSA_DBREGN_AEP_INDEX(tn) ((tn) & 0x07) /* 0..7 for aep0..aep7 */ +#define XTENSA_DBREGN_AEQ_INDEX(tn) ((tn) & 0x03) /* 0..3 for aeq0..aeq3 */ +#define XTENSA_DBREGN_DF_INDEX(tn) ((tn) & 0x0F) /* 0..15 for df0..df15 */ +#define XTENSA_DBREGN_AR_INDEX(tn) ((tn) & 0x3F) /* 0..63 for ar0..ar63 */ +#define XTENSA_DBREGN_SREG_INDEX(tn) ((tn) & 0xFF) /* 0..255 for special registers */ +#define XTENSA_DBREGN_MR_INDEX(tn) ((tn) & 0x03) /* 0..3 for m0..m3 */ +#define XTENSA_DBREGN_UREG_INDEX(tn) ((tn) & 0xFF) /* 0..255 for user registers */ +#define XTENSA_DBREGN_DBAGENT_INDEX(tn) ((tn) & 0xFFF) /* 0..4095 for non-processor */ +/*#define XTENSA_DBREGN_CONTEXT_INDEX(tn) (((tn) >> 20) & 0x1F)*/ /* 0..31 context numbers */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __H_LIBDB_MACROS */ + diff --git a/extra_include/xtensa/xtensa-xer.h b/extra_include/xtensa/xtensa-xer.h index 9098c7d6..900bda33 100644 --- a/extra_include/xtensa/xtensa-xer.h +++ b/extra_include/xtensa/xtensa-xer.h @@ -1,149 +1,149 @@ -/* xer-constants.h -- various constants describing external registers accessed - via wer and rer. - - TODO: find a better prefix. Also conditionalize certain constants based - on number of cores and interrupts actually present. -*/ - -/* - * Copyright (c) 1999-2008 Tensilica Inc. - * - * 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. - */ - -#include - -#define NUM_INTERRUPTS 27 -#define NUM_CORES 4 - -/* Routing of NMI (BInterrupt2) and interrupts 0..n-1 (BInterrupt3+) - RER reads - WER writes - */ - -#define XER_MIROUT 0x0000 -#define XER_MIROUT_LAST (XER_MIROUT + NUM_INTERRUPTS) - - -/* IPI to core M (all 16 causes). - - RER reads - WER clears - */ -#define XER_MIPICAUSE 0x0100 -#define XER_MIPICAUSE_FIELD_A_FIRST 0x0 -#define XER_MIPICAUSE_FIELD_A_LAST 0x0 -#define XER_MIPICAUSE_FIELD_B_FIRST 0x1 -#define XER_MIPICAUSE_FIELD_B_LAST 0x3 -#define XER_MIPICAUSE_FIELD_C_FIRST 0x4 -#define XER_MIPICAUSE_FIELD_C_LAST 0x7 -#define XER_MIPICAUSE_FIELD_D_FIRST 0x8 -#define XER_MIPICAUSE_FIELD_D_LAST 0xF - - -/* IPI from cause bit 0..15 - - RER invalid - WER sets -*/ -#define XER_MIPISET 0x0140 -#define XER_MIPISET_LAST 0x014F - - -/* Global enable - - RER read - WER clear -*/ -#define XER_MIENG 0x0180 - - -/* Global enable - - RER invalid - WER set -*/ -#define XER_MIENG_SET 0x0184 - -/* Global assert - - RER read - WER clear -*/ -#define XER_MIASG 0x0188 - - -/* Global enable - - RER invalid - WER set -*/ -#define XER_MIASG_SET 0x018C - - -/* IPI partition register - - RER read - WER write -*/ -#define XER_PART 0x0190 -#define XER_IPI0 0x0 -#define XER_IPI1 0x1 -#define XER_IPI2 0x2 -#define XER_IPI3 0x3 - -#define XER_PART_ROUTE_IPI(NUM, FIELD) ((NUM) << ((FIELD) << 2)) - -#define XER_PART_ROUTE_IPI_CAUSE(TO_A, TO_B, TO_C, TO_D) \ - (XER_PART_ROUTE_IPI(TO_A, XER_IPI0) | \ - XER_PART_ROUTE_IPI(TO_B, XER_IPI1) | \ - XER_PART_ROUTE_IPI(TO_C, XER_IPI2) | \ - XER_PART_ROUTE_IPI(TO_D, XER_IPI3)) - -#define XER_IPI_WAKE_EXT_INTERRUPT XCHAL_EXTINT0_NUM -#define XER_IPI_WAKE_CAUSE XER_MIPICAUSE_FIELD_C_FIRST -#define XER_IPI_WAKE_ADDRESS (XER_MIPISET + XER_IPI_WAKE_CAUSE) -#define XER_DEFAULT_IPI_ROUTING XER_PART_ROUTE_IPI_CAUSE(XER_IPI1, XER_IPI0, XER_IPI2, XER_IPI3) - - -/* System configuration ID - - RER read - WER invalid -*/ -#define XER_SYSCFGID 0x01A0 - - -/* RunStall to slave processors - - RER read - WER write -*/ -#define XER_MPSCORE 0x0200 - - -/* Cache coherency ON - - RER read - WER write -*/ -#define XER_CCON 0x0220 - - +/* xer-constants.h -- various constants describing external registers accessed + via wer and rer. + + TODO: find a better prefix. Also conditionalize certain constants based + on number of cores and interrupts actually present. +*/ + +/* + * Copyright (c) 1999-2008 Tensilica Inc. + * + * 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. + */ + +#include + +#define NUM_INTERRUPTS 27 +#define NUM_CORES 4 + +/* Routing of NMI (BInterrupt2) and interrupts 0..n-1 (BInterrupt3+) + RER reads + WER writes + */ + +#define XER_MIROUT 0x0000 +#define XER_MIROUT_LAST (XER_MIROUT + NUM_INTERRUPTS) + + +/* IPI to core M (all 16 causes). + + RER reads + WER clears + */ +#define XER_MIPICAUSE 0x0100 +#define XER_MIPICAUSE_FIELD_A_FIRST 0x0 +#define XER_MIPICAUSE_FIELD_A_LAST 0x0 +#define XER_MIPICAUSE_FIELD_B_FIRST 0x1 +#define XER_MIPICAUSE_FIELD_B_LAST 0x3 +#define XER_MIPICAUSE_FIELD_C_FIRST 0x4 +#define XER_MIPICAUSE_FIELD_C_LAST 0x7 +#define XER_MIPICAUSE_FIELD_D_FIRST 0x8 +#define XER_MIPICAUSE_FIELD_D_LAST 0xF + + +/* IPI from cause bit 0..15 + + RER invalid + WER sets +*/ +#define XER_MIPISET 0x0140 +#define XER_MIPISET_LAST 0x014F + + +/* Global enable + + RER read + WER clear +*/ +#define XER_MIENG 0x0180 + + +/* Global enable + + RER invalid + WER set +*/ +#define XER_MIENG_SET 0x0184 + +/* Global assert + + RER read + WER clear +*/ +#define XER_MIASG 0x0188 + + +/* Global enable + + RER invalid + WER set +*/ +#define XER_MIASG_SET 0x018C + + +/* IPI partition register + + RER read + WER write +*/ +#define XER_PART 0x0190 +#define XER_IPI0 0x0 +#define XER_IPI1 0x1 +#define XER_IPI2 0x2 +#define XER_IPI3 0x3 + +#define XER_PART_ROUTE_IPI(NUM, FIELD) ((NUM) << ((FIELD) << 2)) + +#define XER_PART_ROUTE_IPI_CAUSE(TO_A, TO_B, TO_C, TO_D) \ + (XER_PART_ROUTE_IPI(TO_A, XER_IPI0) | \ + XER_PART_ROUTE_IPI(TO_B, XER_IPI1) | \ + XER_PART_ROUTE_IPI(TO_C, XER_IPI2) | \ + XER_PART_ROUTE_IPI(TO_D, XER_IPI3)) + +#define XER_IPI_WAKE_EXT_INTERRUPT XCHAL_EXTINT0_NUM +#define XER_IPI_WAKE_CAUSE XER_MIPICAUSE_FIELD_C_FIRST +#define XER_IPI_WAKE_ADDRESS (XER_MIPISET + XER_IPI_WAKE_CAUSE) +#define XER_DEFAULT_IPI_ROUTING XER_PART_ROUTE_IPI_CAUSE(XER_IPI1, XER_IPI0, XER_IPI2, XER_IPI3) + + +/* System configuration ID + + RER read + WER invalid +*/ +#define XER_SYSCFGID 0x01A0 + + +/* RunStall to slave processors + + RER read + WER write +*/ +#define XER_MPSCORE 0x0200 + + +/* Cache coherency ON + + RER read + WER write +*/ +#define XER_CCON 0x0220 + + diff --git a/extra_include/xtensa/xtruntime-frames.h b/extra_include/xtensa/xtruntime-frames.h index 793a69f0..4d0cde9f 100644 --- a/extra_include/xtensa/xtruntime-frames.h +++ b/extra_include/xtensa/xtruntime-frames.h @@ -1,160 +1,160 @@ -/* xtruntime-frames.h - exception stack frames for single-threaded run-time */ -/* $Id: //depot/rel/Boreal/Xtensa/OS/include/xtensa/xtruntime-frames.h#2 $ */ - -/* - * Copyright (c) 2002-2007 Tensilica Inc. - * - * 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 _XTRUNTIME_FRAMES_H_ -#define _XTRUNTIME_FRAMES_H_ - -#include - -/* Macros that help define structures for both C and assembler: */ -#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) -#define STRUCT_BEGIN .pushsection .text; .struct 0 -#define STRUCT_FIELD(ctype,size,pre,name) pre##name: .space size -#define STRUCT_AFIELD(ctype,size,pre,name,n) pre##name: .space (size)*(n) -#define STRUCT_END(sname) sname##Size:; .popsection -#else /*_ASMLANGUAGE||__ASSEMBLER__*/ -#define STRUCT_BEGIN typedef struct { -#define STRUCT_FIELD(ctype,size,pre,name) ctype name; -#define STRUCT_AFIELD(ctype,size,pre,name,n) ctype name[n]; -#define STRUCT_END(sname) } sname; -#endif /*_ASMLANGUAGE||__ASSEMBLER__*/ - - -/* - * Kernel vector mode exception stack frame. - * - * NOTE: due to the limited range of addi used in the current - * kernel exception vector, and the fact that historically - * the vector is limited to 12 bytes, the size of this - * stack frame is limited to 128 bytes (currently at 64). - */ -STRUCT_BEGIN -STRUCT_FIELD (long,4,KEXC_,pc) /* "parm" */ -STRUCT_FIELD (long,4,KEXC_,ps) -STRUCT_AFIELD(long,4,KEXC_,areg, 4) /* a12 .. a15 */ -STRUCT_FIELD (long,4,KEXC_,sar) /* "save" */ -#if XCHAL_HAVE_LOOPS -STRUCT_FIELD (long,4,KEXC_,lcount) -STRUCT_FIELD (long,4,KEXC_,lbeg) -STRUCT_FIELD (long,4,KEXC_,lend) -#endif -#if XCHAL_HAVE_MAC16 -STRUCT_FIELD (long,4,KEXC_,acclo) -STRUCT_FIELD (long,4,KEXC_,acchi) -STRUCT_AFIELD(long,4,KEXC_,mr, 4) -#endif -STRUCT_END(KernelFrame) - - -/* - * User vector mode exception stack frame: - * - * WARNING: if you modify this structure, you MUST modify the - * computation of the pad size (ALIGNPAD) accordingly. - */ -STRUCT_BEGIN -STRUCT_FIELD (long,4,UEXC_,pc) -STRUCT_FIELD (long,4,UEXC_,ps) -STRUCT_FIELD (long,4,UEXC_,sar) -STRUCT_FIELD (long,4,UEXC_,vpri) -#ifdef __XTENSA_CALL0_ABI__ -STRUCT_FIELD (long,4,UEXC_,a0) -#endif -STRUCT_FIELD (long,4,UEXC_,a2) -STRUCT_FIELD (long,4,UEXC_,a3) -STRUCT_FIELD (long,4,UEXC_,a4) -STRUCT_FIELD (long,4,UEXC_,a5) -#ifdef __XTENSA_CALL0_ABI__ -STRUCT_FIELD (long,4,UEXC_,a6) -STRUCT_FIELD (long,4,UEXC_,a7) -STRUCT_FIELD (long,4,UEXC_,a8) -STRUCT_FIELD (long,4,UEXC_,a9) -STRUCT_FIELD (long,4,UEXC_,a10) -STRUCT_FIELD (long,4,UEXC_,a11) -STRUCT_FIELD (long,4,UEXC_,a12) -STRUCT_FIELD (long,4,UEXC_,a13) -STRUCT_FIELD (long,4,UEXC_,a14) -STRUCT_FIELD (long,4,UEXC_,a15) -#endif -STRUCT_FIELD (long,4,UEXC_,exccause) /* NOTE: can probably rid of this one (pass direct) */ -#if XCHAL_HAVE_LOOPS -STRUCT_FIELD (long,4,UEXC_,lcount) -STRUCT_FIELD (long,4,UEXC_,lbeg) -STRUCT_FIELD (long,4,UEXC_,lend) -#endif -#if XCHAL_HAVE_MAC16 -STRUCT_FIELD (long,4,UEXC_,acclo) -STRUCT_FIELD (long,4,UEXC_,acchi) -STRUCT_AFIELD(long,4,UEXC_,mr, 4) -#endif -/* ALIGNPAD is the 16-byte alignment padding. */ -#ifdef __XTENSA_CALL0_ABI__ -# define CALL0_ABI 1 -#else -# define CALL0_ABI 0 -#endif -#define ALIGNPAD ((3 + XCHAL_HAVE_LOOPS*1 + XCHAL_HAVE_MAC16*2 + CALL0_ABI*1) & 3) -#if ALIGNPAD -STRUCT_AFIELD(long,4,UEXC_,pad, ALIGNPAD) /* 16-byte alignment padding */ -#endif -/*STRUCT_AFIELD(char,1,UEXC_,ureg, (XCHAL_CPEXTRA_SA_SIZE_TOR2+3)&-4)*/ /* not used, and doesn't take alignment into account */ -STRUCT_END(UserFrame) - - -#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) - - -/* Check for UserFrameSize small enough not to require rounding...: */ - /* Skip 16-byte save area, then 32-byte space for 8 regs of call12 - * (which overlaps with 16-byte GCC nested func chaining area), - * then exception stack frame: */ - .set UserFrameTotalSize, 16+32+UserFrameSize - /* Greater than 112 bytes? (max range of ADDI, both signs, when aligned to 16 bytes): */ - .ifgt UserFrameTotalSize-112 - /* Round up to 256-byte multiple to accelerate immediate adds: */ - .set UserFrameTotalSize, ((UserFrameTotalSize+255) & 0xFFFFFF00) - .endif -# define ESF_TOTALSIZE UserFrameTotalSize - -#endif /* _ASMLANGUAGE || __ASSEMBLER__ */ - - -#if XCHAL_NUM_CONTEXTS > 1 -/* Structure of info stored on new context's stack for setup: */ -STRUCT_BEGIN -STRUCT_FIELD (long,4,INFO_,sp) -STRUCT_FIELD (long,4,INFO_,arg1) -STRUCT_FIELD (long,4,INFO_,funcpc) -STRUCT_FIELD (long,4,INFO_,prevps) -STRUCT_END(SetupInfo) -#endif - - -#define KERNELSTACKSIZE 1024 - - -#endif /* _XTRUNTIME_FRAMES_H_ */ - +/* xtruntime-frames.h - exception stack frames for single-threaded run-time */ +/* $Id: //depot/rel/Boreal/Xtensa/OS/include/xtensa/xtruntime-frames.h#2 $ */ + +/* + * Copyright (c) 2002-2007 Tensilica Inc. + * + * 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 _XTRUNTIME_FRAMES_H_ +#define _XTRUNTIME_FRAMES_H_ + +#include + +/* Macros that help define structures for both C and assembler: */ +#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) +#define STRUCT_BEGIN .pushsection .text; .struct 0 +#define STRUCT_FIELD(ctype,size,pre,name) pre##name: .space size +#define STRUCT_AFIELD(ctype,size,pre,name,n) pre##name: .space (size)*(n) +#define STRUCT_END(sname) sname##Size:; .popsection +#else /*_ASMLANGUAGE||__ASSEMBLER__*/ +#define STRUCT_BEGIN typedef struct { +#define STRUCT_FIELD(ctype,size,pre,name) ctype name; +#define STRUCT_AFIELD(ctype,size,pre,name,n) ctype name[n]; +#define STRUCT_END(sname) } sname; +#endif /*_ASMLANGUAGE||__ASSEMBLER__*/ + + +/* + * Kernel vector mode exception stack frame. + * + * NOTE: due to the limited range of addi used in the current + * kernel exception vector, and the fact that historically + * the vector is limited to 12 bytes, the size of this + * stack frame is limited to 128 bytes (currently at 64). + */ +STRUCT_BEGIN +STRUCT_FIELD (long,4,KEXC_,pc) /* "parm" */ +STRUCT_FIELD (long,4,KEXC_,ps) +STRUCT_AFIELD(long,4,KEXC_,areg, 4) /* a12 .. a15 */ +STRUCT_FIELD (long,4,KEXC_,sar) /* "save" */ +#if XCHAL_HAVE_LOOPS +STRUCT_FIELD (long,4,KEXC_,lcount) +STRUCT_FIELD (long,4,KEXC_,lbeg) +STRUCT_FIELD (long,4,KEXC_,lend) +#endif +#if XCHAL_HAVE_MAC16 +STRUCT_FIELD (long,4,KEXC_,acclo) +STRUCT_FIELD (long,4,KEXC_,acchi) +STRUCT_AFIELD(long,4,KEXC_,mr, 4) +#endif +STRUCT_END(KernelFrame) + + +/* + * User vector mode exception stack frame: + * + * WARNING: if you modify this structure, you MUST modify the + * computation of the pad size (ALIGNPAD) accordingly. + */ +STRUCT_BEGIN +STRUCT_FIELD (long,4,UEXC_,pc) +STRUCT_FIELD (long,4,UEXC_,ps) +STRUCT_FIELD (long,4,UEXC_,sar) +STRUCT_FIELD (long,4,UEXC_,vpri) +#ifdef __XTENSA_CALL0_ABI__ +STRUCT_FIELD (long,4,UEXC_,a0) +#endif +STRUCT_FIELD (long,4,UEXC_,a2) +STRUCT_FIELD (long,4,UEXC_,a3) +STRUCT_FIELD (long,4,UEXC_,a4) +STRUCT_FIELD (long,4,UEXC_,a5) +#ifdef __XTENSA_CALL0_ABI__ +STRUCT_FIELD (long,4,UEXC_,a6) +STRUCT_FIELD (long,4,UEXC_,a7) +STRUCT_FIELD (long,4,UEXC_,a8) +STRUCT_FIELD (long,4,UEXC_,a9) +STRUCT_FIELD (long,4,UEXC_,a10) +STRUCT_FIELD (long,4,UEXC_,a11) +STRUCT_FIELD (long,4,UEXC_,a12) +STRUCT_FIELD (long,4,UEXC_,a13) +STRUCT_FIELD (long,4,UEXC_,a14) +STRUCT_FIELD (long,4,UEXC_,a15) +#endif +STRUCT_FIELD (long,4,UEXC_,exccause) /* NOTE: can probably rid of this one (pass direct) */ +#if XCHAL_HAVE_LOOPS +STRUCT_FIELD (long,4,UEXC_,lcount) +STRUCT_FIELD (long,4,UEXC_,lbeg) +STRUCT_FIELD (long,4,UEXC_,lend) +#endif +#if XCHAL_HAVE_MAC16 +STRUCT_FIELD (long,4,UEXC_,acclo) +STRUCT_FIELD (long,4,UEXC_,acchi) +STRUCT_AFIELD(long,4,UEXC_,mr, 4) +#endif +/* ALIGNPAD is the 16-byte alignment padding. */ +#ifdef __XTENSA_CALL0_ABI__ +# define CALL0_ABI 1 +#else +# define CALL0_ABI 0 +#endif +#define ALIGNPAD ((3 + XCHAL_HAVE_LOOPS*1 + XCHAL_HAVE_MAC16*2 + CALL0_ABI*1) & 3) +#if ALIGNPAD +STRUCT_AFIELD(long,4,UEXC_,pad, ALIGNPAD) /* 16-byte alignment padding */ +#endif +/*STRUCT_AFIELD(char,1,UEXC_,ureg, (XCHAL_CPEXTRA_SA_SIZE_TOR2+3)&-4)*/ /* not used, and doesn't take alignment into account */ +STRUCT_END(UserFrame) + + +#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) + + +/* Check for UserFrameSize small enough not to require rounding...: */ + /* Skip 16-byte save area, then 32-byte space for 8 regs of call12 + * (which overlaps with 16-byte GCC nested func chaining area), + * then exception stack frame: */ + .set UserFrameTotalSize, 16+32+UserFrameSize + /* Greater than 112 bytes? (max range of ADDI, both signs, when aligned to 16 bytes): */ + .ifgt UserFrameTotalSize-112 + /* Round up to 256-byte multiple to accelerate immediate adds: */ + .set UserFrameTotalSize, ((UserFrameTotalSize+255) & 0xFFFFFF00) + .endif +# define ESF_TOTALSIZE UserFrameTotalSize + +#endif /* _ASMLANGUAGE || __ASSEMBLER__ */ + + +#if XCHAL_NUM_CONTEXTS > 1 +/* Structure of info stored on new context's stack for setup: */ +STRUCT_BEGIN +STRUCT_FIELD (long,4,INFO_,sp) +STRUCT_FIELD (long,4,INFO_,arg1) +STRUCT_FIELD (long,4,INFO_,funcpc) +STRUCT_FIELD (long,4,INFO_,prevps) +STRUCT_END(SetupInfo) +#endif + + +#define KERNELSTACKSIZE 1024 + + +#endif /* _XTRUNTIME_FRAMES_H_ */ + diff --git a/extra_include/xtensa/xtruntime.h b/extra_include/xtensa/xtruntime.h index 7ca6bd3c..85d39aec 100644 --- a/extra_include/xtensa/xtruntime.h +++ b/extra_include/xtensa/xtruntime.h @@ -1,184 +1,184 @@ -/* - * xtruntime.h -- general C definitions for single-threaded run-time - * - * Copyright (c) 2002-2008 Tensilica Inc. - * - * 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 XTRUNTIME_H -#define XTRUNTIME_H - -#include -#include - -#ifndef XTSTR -#define _XTSTR(x) # x -#define XTSTR(x) _XTSTR(x) -#endif - -#define _xtos_set_execption_handler _xtos_set_exception_handler /* backward compatibility */ -#define _xtos_set_saved_intenable _xtos_ints_on /* backward compatibility */ -#define _xtos_clear_saved_intenable _xtos_ints_off /* backward compatibility */ - -#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__) - -#ifdef __cplusplus -extern "C" { -#endif - -/*typedef void (_xtos_timerdelta_func)(int);*/ -#ifdef __cplusplus -typedef void (_xtos_handler_func)(...); -#else -typedef void (_xtos_handler_func)(); -#endif -typedef _xtos_handler_func *_xtos_handler; - -/* - * unsigned XTOS_SET_INTLEVEL(int intlevel); - * This macro sets the current interrupt level. - * The 'intlevel' parameter must be a constant. - * This macro returns a 32-bit value that must be passed to - * XTOS_RESTORE_INTLEVEL() to restore the previous interrupt level. - * XTOS_RESTORE_JUST_INTLEVEL() also does this, but in XEA2 configs - * it restores only PS.INTLEVEL rather than the entire PS register - * and thus is slower. - */ -#if !XCHAL_HAVE_INTERRUPTS -# define XTOS_SET_INTLEVEL(intlevel) 0 -# define XTOS_SET_MIN_INTLEVEL(intlevel) 0 -# define XTOS_RESTORE_INTLEVEL(restoreval) -# define XTOS_RESTORE_JUST_INTLEVEL(restoreval) -#elif XCHAL_HAVE_XEA2 -/* In XEA2, we can simply safely set PS.INTLEVEL directly: */ -/* NOTE: these asm macros don't modify memory, but they are marked - * as such to act as memory access barriers to the compiler because - * these macros are sometimes used to delineate critical sections; - * function calls are natural barriers (the compiler does not know - * whether a function modifies memory) unless declared to be inlined. */ -# define XTOS_SET_INTLEVEL(intlevel) ({ unsigned __tmp; \ - __asm__ __volatile__( "rsil %0, " XTSTR(intlevel) "\n" \ - : "=a" (__tmp) : : "memory" ); \ - __tmp;}) -# define XTOS_SET_MIN_INTLEVEL(intlevel) ({ unsigned __tmp, __tmp2, __tmp3; \ - __asm__ __volatile__( "rsr %0, " XTSTR(PS) "\n" /* get old (current) PS.INTLEVEL */ \ - "movi %2, " XTSTR(intlevel) "\n" \ - "extui %1, %0, 0, 4\n" /* keep only INTLEVEL bits of parameter */ \ - "blt %2, %1, 1f\n" \ - "rsil %0, " XTSTR(intlevel) "\n" \ - "1:\n" \ - : "=a" (__tmp), "=&a" (__tmp2), "=&a" (__tmp3) : : "memory" ); \ - __tmp;}) -# define XTOS_RESTORE_INTLEVEL(restoreval) do{ unsigned __tmp = (restoreval); \ - __asm__ __volatile__( "wsr %0, " XTSTR(PS) " ; rsync\n" \ - : : "a" (__tmp) : "memory" ); \ - }while(0) -# define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_intlevel(restoreval) -#else -/* In XEA1, we have to rely on INTENABLE register virtualization: */ -extern unsigned _xtos_set_vpri( unsigned vpri ); -extern unsigned _xtos_vpri_enabled; /* current virtual priority */ -# define XTOS_SET_INTLEVEL(intlevel) _xtos_set_vpri(~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel)) -# define XTOS_SET_MIN_INTLEVEL(intlevel) _xtos_set_vpri(_xtos_vpri_enabled & ~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel)) -# define XTOS_RESTORE_INTLEVEL(restoreval) _xtos_set_vpri(restoreval) -# define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_vpri(restoreval) -#endif - -/* - * The following macros build upon the above. They are generally used - * instead of invoking the SET_INTLEVEL and SET_MIN_INTLEVEL macros directly. - * They all return a value that can be used with XTOS_RESTORE_INTLEVEL() - * or _xtos_restore_intlevel() or _xtos_restore_just_intlevel() to restore - * the effective interrupt level to what it was before the macro was invoked. - * In XEA2, the DISABLE macros are much faster than the MASK macros - * (in all configs, DISABLE sets the effective interrupt level, whereas MASK - * makes ensures the effective interrupt level is at least the level given - * without lowering it; in XEA2 with INTENABLE virtualization, these macros - * affect PS.INTLEVEL only, not the virtual priority, so DISABLE has partial - * MASK semantics). - * - * A typical critical section sequence might be: - * unsigned rval = XTOS_DISABLE_EXCM_INTERRUPTS; - * ... critical section ... - * XTOS_RESTORE_INTLEVEL(rval); - */ -/* Enable all interrupts (those activated with _xtos_ints_on()): */ -#define XTOS_ENABLE_INTERRUPTS XTOS_SET_INTLEVEL(0) -/* Disable low priority level interrupts (they can interact with the OS): */ -#define XTOS_DISABLE_LOWPRI_INTERRUPTS XTOS_SET_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS) -#define XTOS_MASK_LOWPRI_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS) -/* Disable interrupts that can interact with the OS: */ -#define XTOS_DISABLE_EXCM_INTERRUPTS XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL) -#define XTOS_MASK_EXCM_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XCHAL_EXCM_LEVEL) -#if 0 /* XTOS_LOCK_LEVEL is not exported to applications */ -/* Disable interrupts that can interact with the OS, or manipulate virtual INTENABLE: */ -#define XTOS_DISABLE_LOCK_INTERRUPTS XTOS_SET_INTLEVEL(XTOS_LOCK_LEVEL) -#define XTOS_MASK_LOCK_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XTOS_LOCK_LEVEL) -#endif -/* Disable ALL interrupts (not for common use, particularly if one's processor - * configuration has high-level interrupts and one cares about their latency): */ -#define XTOS_DISABLE_ALL_INTERRUPTS XTOS_SET_INTLEVEL(15) - - -extern unsigned int _xtos_ints_off( unsigned int mask ); -extern unsigned int _xtos_ints_on( unsigned int mask ); -extern unsigned _xtos_set_intlevel( int intlevel ); -extern unsigned _xtos_set_min_intlevel( int intlevel ); -extern unsigned _xtos_restore_intlevel( unsigned restoreval ); -extern unsigned _xtos_restore_just_intlevel( unsigned restoreval ); -extern _xtos_handler _xtos_set_interrupt_handler( int n, _xtos_handler f ); -extern _xtos_handler _xtos_set_interrupt_handler_arg( int n, _xtos_handler f, void *arg ); -extern _xtos_handler _xtos_set_exception_handler( int n, _xtos_handler f ); - -extern void _xtos_memep_initrams( void ); -extern void _xtos_memep_enable( int flags ); - -/* Deprecated (but kept because they were documented): */ -extern unsigned int _xtos_read_ints( void ); /* use xthal_get_interrupt() instead */ -extern void _xtos_clear_ints( unsigned int mask ); /* use xthal_set_intclear() instead */ - -#if XCHAL_NUM_CONTEXTS > 1 -extern unsigned _xtos_init_context(int context_num, int stack_size, - _xtos_handler_func *start_func, int arg1); -#endif - -/* Deprecated: */ -#if XCHAL_NUM_TIMERS > 0 -extern void _xtos_timer_0_delta( int cycles ); -#endif -#if XCHAL_NUM_TIMERS > 1 -extern void _xtos_timer_1_delta( int cycles ); -#endif -#if XCHAL_NUM_TIMERS > 2 -extern void _xtos_timer_2_delta( int cycles ); -#endif -#if XCHAL_NUM_TIMERS > 3 -extern void _xtos_timer_3_delta( int cycles ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* !_ASMLANGUAGE && !__ASSEMBLER__ */ - -#endif /* XTRUNTIME_H */ - +/* + * xtruntime.h -- general C definitions for single-threaded run-time + * + * Copyright (c) 2002-2008 Tensilica Inc. + * + * 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 XTRUNTIME_H +#define XTRUNTIME_H + +#include +#include + +#ifndef XTSTR +#define _XTSTR(x) # x +#define XTSTR(x) _XTSTR(x) +#endif + +#define _xtos_set_execption_handler _xtos_set_exception_handler /* backward compatibility */ +#define _xtos_set_saved_intenable _xtos_ints_on /* backward compatibility */ +#define _xtos_clear_saved_intenable _xtos_ints_off /* backward compatibility */ + +#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__) + +#ifdef __cplusplus +extern "C" { +#endif + +/*typedef void (_xtos_timerdelta_func)(int);*/ +#ifdef __cplusplus +typedef void (_xtos_handler_func)(...); +#else +typedef void (_xtos_handler_func)(); +#endif +typedef _xtos_handler_func *_xtos_handler; + +/* + * unsigned XTOS_SET_INTLEVEL(int intlevel); + * This macro sets the current interrupt level. + * The 'intlevel' parameter must be a constant. + * This macro returns a 32-bit value that must be passed to + * XTOS_RESTORE_INTLEVEL() to restore the previous interrupt level. + * XTOS_RESTORE_JUST_INTLEVEL() also does this, but in XEA2 configs + * it restores only PS.INTLEVEL rather than the entire PS register + * and thus is slower. + */ +#if !XCHAL_HAVE_INTERRUPTS +# define XTOS_SET_INTLEVEL(intlevel) 0 +# define XTOS_SET_MIN_INTLEVEL(intlevel) 0 +# define XTOS_RESTORE_INTLEVEL(restoreval) +# define XTOS_RESTORE_JUST_INTLEVEL(restoreval) +#elif XCHAL_HAVE_XEA2 +/* In XEA2, we can simply safely set PS.INTLEVEL directly: */ +/* NOTE: these asm macros don't modify memory, but they are marked + * as such to act as memory access barriers to the compiler because + * these macros are sometimes used to delineate critical sections; + * function calls are natural barriers (the compiler does not know + * whether a function modifies memory) unless declared to be inlined. */ +# define XTOS_SET_INTLEVEL(intlevel) ({ unsigned __tmp; \ + __asm__ __volatile__( "rsil %0, " XTSTR(intlevel) "\n" \ + : "=a" (__tmp) : : "memory" ); \ + __tmp;}) +# define XTOS_SET_MIN_INTLEVEL(intlevel) ({ unsigned __tmp, __tmp2, __tmp3; \ + __asm__ __volatile__( "rsr %0, " XTSTR(PS) "\n" /* get old (current) PS.INTLEVEL */ \ + "movi %2, " XTSTR(intlevel) "\n" \ + "extui %1, %0, 0, 4\n" /* keep only INTLEVEL bits of parameter */ \ + "blt %2, %1, 1f\n" \ + "rsil %0, " XTSTR(intlevel) "\n" \ + "1:\n" \ + : "=a" (__tmp), "=&a" (__tmp2), "=&a" (__tmp3) : : "memory" ); \ + __tmp;}) +# define XTOS_RESTORE_INTLEVEL(restoreval) do{ unsigned __tmp = (restoreval); \ + __asm__ __volatile__( "wsr %0, " XTSTR(PS) " ; rsync\n" \ + : : "a" (__tmp) : "memory" ); \ + }while(0) +# define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_intlevel(restoreval) +#else +/* In XEA1, we have to rely on INTENABLE register virtualization: */ +extern unsigned _xtos_set_vpri( unsigned vpri ); +extern unsigned _xtos_vpri_enabled; /* current virtual priority */ +# define XTOS_SET_INTLEVEL(intlevel) _xtos_set_vpri(~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel)) +# define XTOS_SET_MIN_INTLEVEL(intlevel) _xtos_set_vpri(_xtos_vpri_enabled & ~XCHAL_INTLEVEL_ANDBELOW_MASK(intlevel)) +# define XTOS_RESTORE_INTLEVEL(restoreval) _xtos_set_vpri(restoreval) +# define XTOS_RESTORE_JUST_INTLEVEL(restoreval) _xtos_set_vpri(restoreval) +#endif + +/* + * The following macros build upon the above. They are generally used + * instead of invoking the SET_INTLEVEL and SET_MIN_INTLEVEL macros directly. + * They all return a value that can be used with XTOS_RESTORE_INTLEVEL() + * or _xtos_restore_intlevel() or _xtos_restore_just_intlevel() to restore + * the effective interrupt level to what it was before the macro was invoked. + * In XEA2, the DISABLE macros are much faster than the MASK macros + * (in all configs, DISABLE sets the effective interrupt level, whereas MASK + * makes ensures the effective interrupt level is at least the level given + * without lowering it; in XEA2 with INTENABLE virtualization, these macros + * affect PS.INTLEVEL only, not the virtual priority, so DISABLE has partial + * MASK semantics). + * + * A typical critical section sequence might be: + * unsigned rval = XTOS_DISABLE_EXCM_INTERRUPTS; + * ... critical section ... + * XTOS_RESTORE_INTLEVEL(rval); + */ +/* Enable all interrupts (those activated with _xtos_ints_on()): */ +#define XTOS_ENABLE_INTERRUPTS XTOS_SET_INTLEVEL(0) +/* Disable low priority level interrupts (they can interact with the OS): */ +#define XTOS_DISABLE_LOWPRI_INTERRUPTS XTOS_SET_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS) +#define XTOS_MASK_LOWPRI_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XCHAL_NUM_LOWPRI_LEVELS) +/* Disable interrupts that can interact with the OS: */ +#define XTOS_DISABLE_EXCM_INTERRUPTS XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL) +#define XTOS_MASK_EXCM_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XCHAL_EXCM_LEVEL) +#if 0 /* XTOS_LOCK_LEVEL is not exported to applications */ +/* Disable interrupts that can interact with the OS, or manipulate virtual INTENABLE: */ +#define XTOS_DISABLE_LOCK_INTERRUPTS XTOS_SET_INTLEVEL(XTOS_LOCK_LEVEL) +#define XTOS_MASK_LOCK_INTERRUPTS XTOS_SET_MIN_INTLEVEL(XTOS_LOCK_LEVEL) +#endif +/* Disable ALL interrupts (not for common use, particularly if one's processor + * configuration has high-level interrupts and one cares about their latency): */ +#define XTOS_DISABLE_ALL_INTERRUPTS XTOS_SET_INTLEVEL(15) + + +extern unsigned int _xtos_ints_off( unsigned int mask ); +extern unsigned int _xtos_ints_on( unsigned int mask ); +extern unsigned _xtos_set_intlevel( int intlevel ); +extern unsigned _xtos_set_min_intlevel( int intlevel ); +extern unsigned _xtos_restore_intlevel( unsigned restoreval ); +extern unsigned _xtos_restore_just_intlevel( unsigned restoreval ); +extern _xtos_handler _xtos_set_interrupt_handler( int n, _xtos_handler f ); +extern _xtos_handler _xtos_set_interrupt_handler_arg( int n, _xtos_handler f, void *arg ); +extern _xtos_handler _xtos_set_exception_handler( int n, _xtos_handler f ); + +extern void _xtos_memep_initrams( void ); +extern void _xtos_memep_enable( int flags ); + +/* Deprecated (but kept because they were documented): */ +extern unsigned int _xtos_read_ints( void ); /* use xthal_get_interrupt() instead */ +extern void _xtos_clear_ints( unsigned int mask ); /* use xthal_set_intclear() instead */ + +#if XCHAL_NUM_CONTEXTS > 1 +extern unsigned _xtos_init_context(int context_num, int stack_size, + _xtos_handler_func *start_func, int arg1); +#endif + +/* Deprecated: */ +#if XCHAL_NUM_TIMERS > 0 +extern void _xtos_timer_0_delta( int cycles ); +#endif +#if XCHAL_NUM_TIMERS > 1 +extern void _xtos_timer_1_delta( int cycles ); +#endif +#if XCHAL_NUM_TIMERS > 2 +extern void _xtos_timer_2_delta( int cycles ); +#endif +#if XCHAL_NUM_TIMERS > 3 +extern void _xtos_timer_3_delta( int cycles ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !_ASMLANGUAGE && !__ASSEMBLER__ */ + +#endif /* XTRUNTIME_H */ + diff --git a/include/espressif/esp8266/eagle_soc.h b/include/espressif/esp8266/eagle_soc.h index 9f6f3516..6b50454d 100644 --- a/include/espressif/esp8266/eagle_soc.h +++ b/include/espressif/esp8266/eagle_soc.h @@ -1,126 +1,126 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 _EAGLE_SOC_H_ -#define _EAGLE_SOC_H_ - -//Register Bits{{ -#define BIT31 0x80000000 -#define BIT30 0x40000000 -#define BIT29 0x20000000 -#define BIT28 0x10000000 -#define BIT27 0x08000000 -#define BIT26 0x04000000 -#define BIT25 0x02000000 -#define BIT24 0x01000000 -#define BIT23 0x00800000 -#define BIT22 0x00400000 -#define BIT21 0x00200000 -#define BIT20 0x00100000 -#define BIT19 0x00080000 -#define BIT18 0x00040000 -#define BIT17 0x00020000 -#define BIT16 0x00010000 -#define BIT15 0x00008000 -#define BIT14 0x00004000 -#define BIT13 0x00002000 -#define BIT12 0x00001000 -#define BIT11 0x00000800 -#define BIT10 0x00000400 -#define BIT9 0x00000200 -#define BIT8 0x00000100 -#define BIT7 0x00000080 -#define BIT6 0x00000040 -#define BIT5 0x00000020 -#define BIT4 0x00000010 -#define BIT3 0x00000008 -#define BIT2 0x00000004 -#define BIT1 0x00000002 -#define BIT0 0x00000001 -//}} - -//Registers Operation {{ -#define ETS_UNCACHED_ADDR(addr) (addr) -#define ETS_CACHED_ADDR(addr) (addr) - -#define READ_PERI_REG(addr) (*((volatile uint32 *)ETS_UNCACHED_ADDR(addr))) -#define WRITE_PERI_REG(addr, val) (*((volatile uint32 *)ETS_UNCACHED_ADDR(addr))) = (uint32)(val) -#define CLEAR_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg) & (~(mask)))) -#define SET_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg) | (mask))) -#define GET_PERI_REG_BITS(reg, hipos, lowpos) ((READ_PERI_REG(reg) >> (lowpos)) & ((1 << ((hipos) - (lowpos) + 1)) - 1)) -#define SET_PERI_REG_BITS(reg, bit_map, value, shift) (WRITE_PERI_REG((reg), (READ_PERI_REG(reg) & (~((bit_map) << (shift)))) | ((value) << (shift)) )) -//}} - -//Periheral Clock {{ -#define CPU_CLK_FREQ 80 * 1000000 // unit: Hz -#define APB_CLK_FREQ CPU_CLK_FREQ -#define UART_CLK_FREQ APB_CLK_FREQ -#define TIMER_CLK_FREQ (APB_CLK_FREQ >> 8) // divided by 256 -//}} - -//Peripheral device base address define{{ -#define PERIPHS_DPORT_BASEADDR 0x3ff00000 -#define PERIPHS_RTC_BASEADDR 0x60000700 -//}} - -//DPORT{{ -#define HOST_INF_SEL (PERIPHS_DPORT_BASEADDR + 0x28) -#define DPORT_LINK_DEVICE_SEL 0x000000FF -#define DPORT_LINK_DEVICE_SEL_S 8 -#define DPORT_PERI_IO_SWAP 0x000000FF -#define DPORT_PERI_IO_SWAP_S 0 -#define PERI_IO_CSPI_OVERLAP (BIT(7)) // two spi masters on cspi -#define PERI_IO_HSPI_OVERLAP (BIT(6)) // two spi masters on hspi -#define PERI_IO_HSPI_PRIO (BIT(5)) // hspi is with the higher prior -#define PERI_IO_UART1_PIN_SWAP (BIT(3)) // swap uart1 pins (u1rxd <-> u1cts), (u1txd <-> u1rts) -#define PERI_IO_UART0_PIN_SWAP (BIT(2)) // swap uart0 pins (u0rxd <-> u0cts), (u0txd <-> u0rts) -#define PERI_IO_SPI_PORT_SWAP (BIT(1)) // swap two spi -#define PERI_IO_UART_PORT_SWAP (BIT(0)) // swap two uart -//}} - -//Interrupt remap control registers define{{ -#define EDGE_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR + 0x04) -#define TM1_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) -#define TM1_EDGE_INT_DISABLE() CLEAR_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) -//}} - -//RTC reg {{ -#define REG_RTC_BASE PERIPHS_RTC_BASEADDR - -#define RTC_SLP_VAL (REG_RTC_BASE + 0x004) // the target value of RTC_COUNTER for wakeup from light-sleep/deep-sleep -#define RTC_SLP_CNT_VAL (REG_RTC_BASE + 0x01C) // the current value of RTC_COUNTER - -#define RTC_SCRATCH0 (REG_RTC_BASE + 0x030) // the register for software to save some values for watchdog reset -#define RTC_SCRATCH1 (REG_RTC_BASE + 0x034) // the register for software to save some values for watchdog reset -#define RTC_SCRATCH2 (REG_RTC_BASE + 0x038) // the register for software to save some values for watchdog reset -#define RTC_SCRATCH3 (REG_RTC_BASE + 0x03C) // the register for software to save some values for watchdog reset - -#define RTC_GPIO_OUT (REG_RTC_BASE + 0x068) // used by gpio16 -#define RTC_GPIO_ENABLE (REG_RTC_BASE + 0x074) -#define RTC_GPIO_IN_DATA (REG_RTC_BASE + 0x08C) -#define RTC_GPIO_CONF (REG_RTC_BASE + 0x090) -#define PAD_XPD_DCDC_CONF (REG_RTC_BASE + 0x0A0) -//}} - -#endif //_EAGLE_SOC_H_ +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 _EAGLE_SOC_H_ +#define _EAGLE_SOC_H_ + +//Register Bits{{ +#define BIT31 0x80000000 +#define BIT30 0x40000000 +#define BIT29 0x20000000 +#define BIT28 0x10000000 +#define BIT27 0x08000000 +#define BIT26 0x04000000 +#define BIT25 0x02000000 +#define BIT24 0x01000000 +#define BIT23 0x00800000 +#define BIT22 0x00400000 +#define BIT21 0x00200000 +#define BIT20 0x00100000 +#define BIT19 0x00080000 +#define BIT18 0x00040000 +#define BIT17 0x00020000 +#define BIT16 0x00010000 +#define BIT15 0x00008000 +#define BIT14 0x00004000 +#define BIT13 0x00002000 +#define BIT12 0x00001000 +#define BIT11 0x00000800 +#define BIT10 0x00000400 +#define BIT9 0x00000200 +#define BIT8 0x00000100 +#define BIT7 0x00000080 +#define BIT6 0x00000040 +#define BIT5 0x00000020 +#define BIT4 0x00000010 +#define BIT3 0x00000008 +#define BIT2 0x00000004 +#define BIT1 0x00000002 +#define BIT0 0x00000001 +//}} + +//Registers Operation {{ +#define ETS_UNCACHED_ADDR(addr) (addr) +#define ETS_CACHED_ADDR(addr) (addr) + +#define READ_PERI_REG(addr) (*((volatile uint32 *)ETS_UNCACHED_ADDR(addr))) +#define WRITE_PERI_REG(addr, val) (*((volatile uint32 *)ETS_UNCACHED_ADDR(addr))) = (uint32)(val) +#define CLEAR_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg) & (~(mask)))) +#define SET_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg) | (mask))) +#define GET_PERI_REG_BITS(reg, hipos, lowpos) ((READ_PERI_REG(reg) >> (lowpos)) & ((1 << ((hipos) - (lowpos) + 1)) - 1)) +#define SET_PERI_REG_BITS(reg, bit_map, value, shift) (WRITE_PERI_REG((reg), (READ_PERI_REG(reg) & (~((bit_map) << (shift)))) | ((value) << (shift)) )) +//}} + +//Periheral Clock {{ +#define CPU_CLK_FREQ 80 * 1000000 // unit: Hz +#define APB_CLK_FREQ CPU_CLK_FREQ +#define UART_CLK_FREQ APB_CLK_FREQ +#define TIMER_CLK_FREQ (APB_CLK_FREQ >> 8) // divided by 256 +//}} + +//Peripheral device base address define{{ +#define PERIPHS_DPORT_BASEADDR 0x3ff00000 +#define PERIPHS_RTC_BASEADDR 0x60000700 +//}} + +//DPORT{{ +#define HOST_INF_SEL (PERIPHS_DPORT_BASEADDR + 0x28) +#define DPORT_LINK_DEVICE_SEL 0x000000FF +#define DPORT_LINK_DEVICE_SEL_S 8 +#define DPORT_PERI_IO_SWAP 0x000000FF +#define DPORT_PERI_IO_SWAP_S 0 +#define PERI_IO_CSPI_OVERLAP (BIT(7)) // two spi masters on cspi +#define PERI_IO_HSPI_OVERLAP (BIT(6)) // two spi masters on hspi +#define PERI_IO_HSPI_PRIO (BIT(5)) // hspi is with the higher prior +#define PERI_IO_UART1_PIN_SWAP (BIT(3)) // swap uart1 pins (u1rxd <-> u1cts), (u1txd <-> u1rts) +#define PERI_IO_UART0_PIN_SWAP (BIT(2)) // swap uart0 pins (u0rxd <-> u0cts), (u0txd <-> u0rts) +#define PERI_IO_SPI_PORT_SWAP (BIT(1)) // swap two spi +#define PERI_IO_UART_PORT_SWAP (BIT(0)) // swap two uart +//}} + +//Interrupt remap control registers define{{ +#define EDGE_INT_ENABLE_REG (PERIPHS_DPORT_BASEADDR + 0x04) +#define TM1_EDGE_INT_ENABLE() SET_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) +#define TM1_EDGE_INT_DISABLE() CLEAR_PERI_REG_MASK(EDGE_INT_ENABLE_REG, BIT1) +//}} + +//RTC reg {{ +#define REG_RTC_BASE PERIPHS_RTC_BASEADDR + +#define RTC_SLP_VAL (REG_RTC_BASE + 0x004) // the target value of RTC_COUNTER for wakeup from light-sleep/deep-sleep +#define RTC_SLP_CNT_VAL (REG_RTC_BASE + 0x01C) // the current value of RTC_COUNTER + +#define RTC_SCRATCH0 (REG_RTC_BASE + 0x030) // the register for software to save some values for watchdog reset +#define RTC_SCRATCH1 (REG_RTC_BASE + 0x034) // the register for software to save some values for watchdog reset +#define RTC_SCRATCH2 (REG_RTC_BASE + 0x038) // the register for software to save some values for watchdog reset +#define RTC_SCRATCH3 (REG_RTC_BASE + 0x03C) // the register for software to save some values for watchdog reset + +#define RTC_GPIO_OUT (REG_RTC_BASE + 0x068) // used by gpio16 +#define RTC_GPIO_ENABLE (REG_RTC_BASE + 0x074) +#define RTC_GPIO_IN_DATA (REG_RTC_BASE + 0x08C) +#define RTC_GPIO_CONF (REG_RTC_BASE + 0x090) +#define PAD_XPD_DCDC_CONF (REG_RTC_BASE + 0x0A0) +//}} + +#endif //_EAGLE_SOC_H_ diff --git a/include/espressif/esp8266/esp8266.h b/include/espressif/esp8266/esp8266.h index 1eb417f4..66951ae9 100644 --- a/include/espressif/esp8266/esp8266.h +++ b/include/espressif/esp8266/esp8266.h @@ -1,37 +1,37 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __ESP8266_H__ -#define __ESP8266_H__ - -#include "ets_sys.h" -#include "eagle_soc.h" -#include "gpio_register.h" -#include "pin_mux_register.h" -#include "spi_register.h" -#include "timer_register.h" -#include "uart_register.h" - -#endif - +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __ESP8266_H__ +#define __ESP8266_H__ + +#include "ets_sys.h" +#include "eagle_soc.h" +#include "gpio_register.h" +#include "pin_mux_register.h" +#include "spi_register.h" +#include "timer_register.h" +#include "uart_register.h" + +#endif + diff --git a/include/espressif/esp8266/spi_register.h b/include/espressif/esp8266/spi_register.h index 4b7f76d0..500be3a1 100644 --- a/include/espressif/esp8266/spi_register.h +++ b/include/espressif/esp8266/spi_register.h @@ -1,193 +1,193 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 SPI_REGISTER_H_INCLUDED -#define SPI_REGISTER_H_INCLUDED - -#define REG_SPI_BASE(i) (0x60000200 - i*0x100) - -#define SPI_CMD(i) (REG_SPI_BASE(i) + 0x0) -#define SPI_USR (BIT(18)) - -#define SPI_ADDR(i) (REG_SPI_BASE(i) + 0x4) - -#define SPI_CTRL(i) (REG_SPI_BASE(i) + 0x8) -#define SPI_WR_BIT_ORDER (BIT(26)) -#define SPI_RD_BIT_ORDER (BIT(25)) -#define SPI_QIO_MODE (BIT(24)) -#define SPI_DIO_MODE (BIT(23)) -#define SPI_QOUT_MODE (BIT(20)) -#define SPI_DOUT_MODE (BIT(14)) -#define SPI_FASTRD_MODE (BIT(13)) - -#define SPI_RD_STATUS(i) (REG_SPI_BASE(i) + 0x10) - -#define SPI_CTRL2(i) (REG_SPI_BASE(i) + 0x14) -#define SPI_CS_DELAY_NUM 0x0000000F -#define SPI_CS_DELAY_NUM_S 28 -#define SPI_CS_DELAY_MODE 0x00000003 -#define SPI_CS_DELAY_MODE_S 26 -#define SPI_MOSI_DELAY_NUM 0x00000007 -#define SPI_MOSI_DELAY_NUM_S 23 -#define SPI_MOSI_DELAY_MODE 0x00000003 -#define SPI_MOSI_DELAY_MODE_S 21 -#define SPI_MISO_DELAY_NUM 0x00000007 -#define SPI_MISO_DELAY_NUM_S 18 -#define SPI_MISO_DELAY_MODE 0x00000003 -#define SPI_MISO_DELAY_MODE_S 16 - -#define SPI_CLOCK(i) (REG_SPI_BASE(i) + 0x18) -#define SPI_CLK_EQU_SYSCLK (BIT(31)) -#define SPI_CLKDIV_PRE 0x00001FFF -#define SPI_CLKDIV_PRE_S 18 -#define SPI_CLKCNT_N 0x0000003F -#define SPI_CLKCNT_N_S 12 -#define SPI_CLKCNT_H 0x0000003F -#define SPI_CLKCNT_H_S 6 -#define SPI_CLKCNT_L 0x0000003F -#define SPI_CLKCNT_L_S 0 - -#define SPI_USER(i) (REG_SPI_BASE(i) + 0x1C) -#define SPI_USR_COMMAND (BIT(31)) -#define SPI_USR_ADDR (BIT(30)) -#define SPI_USR_DUMMY (BIT(29)) -#define SPI_USR_MISO (BIT(28)) -#define SPI_USR_MOSI (BIT(27)) -#define SPI_USR_MOSI_HIGHPART (BIT(25)) -#define SPI_USR_MISO_HIGHPART (BIT(24)) -#define SPI_SIO (BIT(16)) -#define SPI_FWRITE_QIO (BIT(15)) -#define SPI_FWRITE_DIO (BIT(14)) -#define SPI_FWRITE_QUAD (BIT(13)) -#define SPI_FWRITE_DUAL (BIT(12)) -#define SPI_WR_BYTE_ORDER (BIT(11)) -#define SPI_RD_BYTE_ORDER (BIT(10)) -#define SPI_CK_OUT_EDGE (BIT(7)) -#define SPI_CK_I_EDGE (BIT(6)) -#define SPI_CS_SETUP (BIT(5)) -#define SPI_CS_HOLD (BIT(4)) -#define SPI_FLASH_MODE (BIT(2)) - -#define SPI_USER1(i) (REG_SPI_BASE(i) + 0x20) -#define SPI_USR_ADDR_BITLEN 0x0000003F -#define SPI_USR_ADDR_BITLEN_S 26 -#define SPI_USR_MOSI_BITLEN 0x000001FF -#define SPI_USR_MOSI_BITLEN_S 17 -#define SPI_USR_MISO_BITLEN 0x000001FF -#define SPI_USR_MISO_BITLEN_S 8 -#define SPI_USR_DUMMY_CYCLELEN 0x000000FF -#define SPI_USR_DUMMY_CYCLELEN_S 0 - -#define SPI_USER2(i) (REG_SPI_BASE(i) + 0x24) -#define SPI_USR_COMMAND_BITLEN 0x0000000F -#define SPI_USR_COMMAND_BITLEN_S 28 -#define SPI_USR_COMMAND_VALUE 0x0000FFFF -#define SPI_USR_COMMAND_VALUE_S 0 - -#define SPI_WR_STATUS(i) (REG_SPI_BASE(i) + 0x28) - -#define SPI_PIN(i) (REG_SPI_BASE(i) + 0x2C) -#define SPI_CS2_DIS (BIT(2)) -#define SPI_CS1_DIS (BIT(1)) -#define SPI_CS0_DIS (BIT(0)) - -#define SPI_SLAVE(i) (REG_SPI_BASE(i) + 0x30) -#define SPI_SYNC_RESET (BIT(31)) -#define SPI_SLAVE_MODE (BIT(30)) -#define SPI_SLV_WR_RD_BUF_EN (BIT(29)) -#define SPI_SLV_WR_RD_STA_EN (BIT(28)) -#define SPI_SLV_CMD_DEFINE (BIT(27)) -#define SPI_TRANS_CNT 0x0000000F -#define SPI_TRANS_CNT_S 23 -#define SPI_TRANS_DONE_EN (BIT(9)) -#define SPI_SLV_WR_STA_DONE_EN (BIT(8)) -#define SPI_SLV_RD_STA_DONE_EN (BIT(7)) -#define SPI_SLV_WR_BUF_DONE_EN (BIT(6)) -#define SPI_SLV_RD_BUF_DONE_EN (BIT(5)) -#define SLV_SPI_INT_EN 0x0000001f -#define SLV_SPI_INT_EN_S 5 -#define SPI_TRANS_DONE (BIT(4)) -#define SPI_SLV_WR_STA_DONE (BIT(3)) -#define SPI_SLV_RD_STA_DONE (BIT(2)) -#define SPI_SLV_WR_BUF_DONE (BIT(1)) -#define SPI_SLV_RD_BUF_DONE (BIT(0)) - -#define SPI_SLAVE1(i) (REG_SPI_BASE(i) + 0x34) -#define SPI_SLV_STATUS_BITLEN 0x0000001F -#define SPI_SLV_STATUS_BITLEN_S 27 -#define SPI_SLV_BUF_BITLEN 0x000001FF -#define SPI_SLV_BUF_BITLEN_S 16 -#define SPI_SLV_RD_ADDR_BITLEN 0x0000003F -#define SPI_SLV_RD_ADDR_BITLEN_S 10 -#define SPI_SLV_WR_ADDR_BITLEN 0x0000003F -#define SPI_SLV_WR_ADDR_BITLEN_S 4 -#define SPI_SLV_WRSTA_DUMMY_EN (BIT(3)) -#define SPI_SLV_RDSTA_DUMMY_EN (BIT(2)) -#define SPI_SLV_WRBUF_DUMMY_EN (BIT(1)) -#define SPI_SLV_RDBUF_DUMMY_EN (BIT(0)) - -#define SPI_SLAVE2(i) (REG_SPI_BASE(i) + 0x38) -#define SPI_SLV_WRBUF_DUMMY_CYCLELEN 0x000000FF -#define SPI_SLV_WRBUF_DUMMY_CYCLELEN_S 24 -#define SPI_SLV_RDBUF_DUMMY_CYCLELEN 0x000000FF -#define SPI_SLV_RDBUF_DUMMY_CYCLELEN_S 16 -#define SPI_SLV_WRSTR_DUMMY_CYCLELEN 0x000000FF -#define SPI_SLV_WRSTR_DUMMY_CYCLELEN_S 8 -#define SPI_SLV_RDSTR_DUMMY_CYCLELEN 0x000000FF -#define SPI_SLV_RDSTR_DUMMY_CYCLELEN_S 0 - -#define SPI_SLAVE3(i) (REG_SPI_BASE(i) + 0x3C) -#define SPI_SLV_WRSTA_CMD_VALUE 0x000000FF -#define SPI_SLV_WRSTA_CMD_VALUE_S 24 -#define SPI_SLV_RDSTA_CMD_VALUE 0x000000FF -#define SPI_SLV_RDSTA_CMD_VALUE_S 16 -#define SPI_SLV_WRBUF_CMD_VALUE 0x000000FF -#define SPI_SLV_WRBUF_CMD_VALUE_S 8 -#define SPI_SLV_RDBUF_CMD_VALUE 0x000000FF -#define SPI_SLV_RDBUF_CMD_VALUE_S 0 - -#define SPI_W0(i) (REG_SPI_BASE(i) + 0x40) -#define SPI_W1(i) (REG_SPI_BASE(i) + 0x44) -#define SPI_W2(i) (REG_SPI_BASE(i) + 0x48) -#define SPI_W3(i) (REG_SPI_BASE(i) + 0x4C) -#define SPI_W4(i) (REG_SPI_BASE(i) + 0x50) -#define SPI_W5(i) (REG_SPI_BASE(i) + 0x54) -#define SPI_W6(i) (REG_SPI_BASE(i) + 0x58) -#define SPI_W7(i) (REG_SPI_BASE(i) + 0x5C) -#define SPI_W8(i) (REG_SPI_BASE(i) + 0x60) -#define SPI_W9(i) (REG_SPI_BASE(i) + 0x64) -#define SPI_W10(i) (REG_SPI_BASE(i) + 0x68) -#define SPI_W11(i) (REG_SPI_BASE(i) + 0x6C) -#define SPI_W12(i) (REG_SPI_BASE(i) + 0x70) -#define SPI_W13(i) (REG_SPI_BASE(i) + 0x74) -#define SPI_W14(i) (REG_SPI_BASE(i) + 0x78) -#define SPI_W15(i) (REG_SPI_BASE(i) + 0x7C) - -#define SPI_EXT2(i) (REG_SPI_BASE(i) + 0xF8) - -#define SPI_EXT3(i) (REG_SPI_BASE(i) + 0xFC) -#define SPI_INT_HOLD_ENA 0x00000003 -#define SPI_INT_HOLD_ENA_S 0 - -#endif // SPI_REGISTER_H_INCLUDED +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 SPI_REGISTER_H_INCLUDED +#define SPI_REGISTER_H_INCLUDED + +#define REG_SPI_BASE(i) (0x60000200 - i*0x100) + +#define SPI_CMD(i) (REG_SPI_BASE(i) + 0x0) +#define SPI_USR (BIT(18)) + +#define SPI_ADDR(i) (REG_SPI_BASE(i) + 0x4) + +#define SPI_CTRL(i) (REG_SPI_BASE(i) + 0x8) +#define SPI_WR_BIT_ORDER (BIT(26)) +#define SPI_RD_BIT_ORDER (BIT(25)) +#define SPI_QIO_MODE (BIT(24)) +#define SPI_DIO_MODE (BIT(23)) +#define SPI_QOUT_MODE (BIT(20)) +#define SPI_DOUT_MODE (BIT(14)) +#define SPI_FASTRD_MODE (BIT(13)) + +#define SPI_RD_STATUS(i) (REG_SPI_BASE(i) + 0x10) + +#define SPI_CTRL2(i) (REG_SPI_BASE(i) + 0x14) +#define SPI_CS_DELAY_NUM 0x0000000F +#define SPI_CS_DELAY_NUM_S 28 +#define SPI_CS_DELAY_MODE 0x00000003 +#define SPI_CS_DELAY_MODE_S 26 +#define SPI_MOSI_DELAY_NUM 0x00000007 +#define SPI_MOSI_DELAY_NUM_S 23 +#define SPI_MOSI_DELAY_MODE 0x00000003 +#define SPI_MOSI_DELAY_MODE_S 21 +#define SPI_MISO_DELAY_NUM 0x00000007 +#define SPI_MISO_DELAY_NUM_S 18 +#define SPI_MISO_DELAY_MODE 0x00000003 +#define SPI_MISO_DELAY_MODE_S 16 + +#define SPI_CLOCK(i) (REG_SPI_BASE(i) + 0x18) +#define SPI_CLK_EQU_SYSCLK (BIT(31)) +#define SPI_CLKDIV_PRE 0x00001FFF +#define SPI_CLKDIV_PRE_S 18 +#define SPI_CLKCNT_N 0x0000003F +#define SPI_CLKCNT_N_S 12 +#define SPI_CLKCNT_H 0x0000003F +#define SPI_CLKCNT_H_S 6 +#define SPI_CLKCNT_L 0x0000003F +#define SPI_CLKCNT_L_S 0 + +#define SPI_USER(i) (REG_SPI_BASE(i) + 0x1C) +#define SPI_USR_COMMAND (BIT(31)) +#define SPI_USR_ADDR (BIT(30)) +#define SPI_USR_DUMMY (BIT(29)) +#define SPI_USR_MISO (BIT(28)) +#define SPI_USR_MOSI (BIT(27)) +#define SPI_USR_MOSI_HIGHPART (BIT(25)) +#define SPI_USR_MISO_HIGHPART (BIT(24)) +#define SPI_SIO (BIT(16)) +#define SPI_FWRITE_QIO (BIT(15)) +#define SPI_FWRITE_DIO (BIT(14)) +#define SPI_FWRITE_QUAD (BIT(13)) +#define SPI_FWRITE_DUAL (BIT(12)) +#define SPI_WR_BYTE_ORDER (BIT(11)) +#define SPI_RD_BYTE_ORDER (BIT(10)) +#define SPI_CK_OUT_EDGE (BIT(7)) +#define SPI_CK_I_EDGE (BIT(6)) +#define SPI_CS_SETUP (BIT(5)) +#define SPI_CS_HOLD (BIT(4)) +#define SPI_FLASH_MODE (BIT(2)) + +#define SPI_USER1(i) (REG_SPI_BASE(i) + 0x20) +#define SPI_USR_ADDR_BITLEN 0x0000003F +#define SPI_USR_ADDR_BITLEN_S 26 +#define SPI_USR_MOSI_BITLEN 0x000001FF +#define SPI_USR_MOSI_BITLEN_S 17 +#define SPI_USR_MISO_BITLEN 0x000001FF +#define SPI_USR_MISO_BITLEN_S 8 +#define SPI_USR_DUMMY_CYCLELEN 0x000000FF +#define SPI_USR_DUMMY_CYCLELEN_S 0 + +#define SPI_USER2(i) (REG_SPI_BASE(i) + 0x24) +#define SPI_USR_COMMAND_BITLEN 0x0000000F +#define SPI_USR_COMMAND_BITLEN_S 28 +#define SPI_USR_COMMAND_VALUE 0x0000FFFF +#define SPI_USR_COMMAND_VALUE_S 0 + +#define SPI_WR_STATUS(i) (REG_SPI_BASE(i) + 0x28) + +#define SPI_PIN(i) (REG_SPI_BASE(i) + 0x2C) +#define SPI_CS2_DIS (BIT(2)) +#define SPI_CS1_DIS (BIT(1)) +#define SPI_CS0_DIS (BIT(0)) + +#define SPI_SLAVE(i) (REG_SPI_BASE(i) + 0x30) +#define SPI_SYNC_RESET (BIT(31)) +#define SPI_SLAVE_MODE (BIT(30)) +#define SPI_SLV_WR_RD_BUF_EN (BIT(29)) +#define SPI_SLV_WR_RD_STA_EN (BIT(28)) +#define SPI_SLV_CMD_DEFINE (BIT(27)) +#define SPI_TRANS_CNT 0x0000000F +#define SPI_TRANS_CNT_S 23 +#define SPI_TRANS_DONE_EN (BIT(9)) +#define SPI_SLV_WR_STA_DONE_EN (BIT(8)) +#define SPI_SLV_RD_STA_DONE_EN (BIT(7)) +#define SPI_SLV_WR_BUF_DONE_EN (BIT(6)) +#define SPI_SLV_RD_BUF_DONE_EN (BIT(5)) +#define SLV_SPI_INT_EN 0x0000001f +#define SLV_SPI_INT_EN_S 5 +#define SPI_TRANS_DONE (BIT(4)) +#define SPI_SLV_WR_STA_DONE (BIT(3)) +#define SPI_SLV_RD_STA_DONE (BIT(2)) +#define SPI_SLV_WR_BUF_DONE (BIT(1)) +#define SPI_SLV_RD_BUF_DONE (BIT(0)) + +#define SPI_SLAVE1(i) (REG_SPI_BASE(i) + 0x34) +#define SPI_SLV_STATUS_BITLEN 0x0000001F +#define SPI_SLV_STATUS_BITLEN_S 27 +#define SPI_SLV_BUF_BITLEN 0x000001FF +#define SPI_SLV_BUF_BITLEN_S 16 +#define SPI_SLV_RD_ADDR_BITLEN 0x0000003F +#define SPI_SLV_RD_ADDR_BITLEN_S 10 +#define SPI_SLV_WR_ADDR_BITLEN 0x0000003F +#define SPI_SLV_WR_ADDR_BITLEN_S 4 +#define SPI_SLV_WRSTA_DUMMY_EN (BIT(3)) +#define SPI_SLV_RDSTA_DUMMY_EN (BIT(2)) +#define SPI_SLV_WRBUF_DUMMY_EN (BIT(1)) +#define SPI_SLV_RDBUF_DUMMY_EN (BIT(0)) + +#define SPI_SLAVE2(i) (REG_SPI_BASE(i) + 0x38) +#define SPI_SLV_WRBUF_DUMMY_CYCLELEN 0x000000FF +#define SPI_SLV_WRBUF_DUMMY_CYCLELEN_S 24 +#define SPI_SLV_RDBUF_DUMMY_CYCLELEN 0x000000FF +#define SPI_SLV_RDBUF_DUMMY_CYCLELEN_S 16 +#define SPI_SLV_WRSTR_DUMMY_CYCLELEN 0x000000FF +#define SPI_SLV_WRSTR_DUMMY_CYCLELEN_S 8 +#define SPI_SLV_RDSTR_DUMMY_CYCLELEN 0x000000FF +#define SPI_SLV_RDSTR_DUMMY_CYCLELEN_S 0 + +#define SPI_SLAVE3(i) (REG_SPI_BASE(i) + 0x3C) +#define SPI_SLV_WRSTA_CMD_VALUE 0x000000FF +#define SPI_SLV_WRSTA_CMD_VALUE_S 24 +#define SPI_SLV_RDSTA_CMD_VALUE 0x000000FF +#define SPI_SLV_RDSTA_CMD_VALUE_S 16 +#define SPI_SLV_WRBUF_CMD_VALUE 0x000000FF +#define SPI_SLV_WRBUF_CMD_VALUE_S 8 +#define SPI_SLV_RDBUF_CMD_VALUE 0x000000FF +#define SPI_SLV_RDBUF_CMD_VALUE_S 0 + +#define SPI_W0(i) (REG_SPI_BASE(i) + 0x40) +#define SPI_W1(i) (REG_SPI_BASE(i) + 0x44) +#define SPI_W2(i) (REG_SPI_BASE(i) + 0x48) +#define SPI_W3(i) (REG_SPI_BASE(i) + 0x4C) +#define SPI_W4(i) (REG_SPI_BASE(i) + 0x50) +#define SPI_W5(i) (REG_SPI_BASE(i) + 0x54) +#define SPI_W6(i) (REG_SPI_BASE(i) + 0x58) +#define SPI_W7(i) (REG_SPI_BASE(i) + 0x5C) +#define SPI_W8(i) (REG_SPI_BASE(i) + 0x60) +#define SPI_W9(i) (REG_SPI_BASE(i) + 0x64) +#define SPI_W10(i) (REG_SPI_BASE(i) + 0x68) +#define SPI_W11(i) (REG_SPI_BASE(i) + 0x6C) +#define SPI_W12(i) (REG_SPI_BASE(i) + 0x70) +#define SPI_W13(i) (REG_SPI_BASE(i) + 0x74) +#define SPI_W14(i) (REG_SPI_BASE(i) + 0x78) +#define SPI_W15(i) (REG_SPI_BASE(i) + 0x7C) + +#define SPI_EXT2(i) (REG_SPI_BASE(i) + 0xF8) + +#define SPI_EXT3(i) (REG_SPI_BASE(i) + 0xFC) +#define SPI_INT_HOLD_ENA 0x00000003 +#define SPI_INT_HOLD_ENA_S 0 + +#endif // SPI_REGISTER_H_INCLUDED diff --git a/include/espressif/esp8266/timer_register.h b/include/espressif/esp8266/timer_register.h index 24062202..302147b8 100644 --- a/include/espressif/esp8266/timer_register.h +++ b/include/espressif/esp8266/timer_register.h @@ -1,93 +1,93 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 _TIMER_REGISTER_H_ -#define _TIMER_REGISTER_H_ - -#define PERIPHS_TIMER_BASEDDR 0x60000600 - -#define FRC1_LOAD_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x0) -#define TIMER_FRC1_LOAD_VALUE 0x007FFFFF -#define TIMER_FRC1_LOAD_VALUE_S 0 -#define FRC1_LOAD_DATA_MSB 22 -#define FRC1_LOAD_DATA_LSB 0 -#define FRC1_LOAD_DATA_MASK 0x007fffff - -#define FRC1_COUNT_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x4) -#define TIMER_FRC1_COUNT 0x007FFFFF -#define TIMER_FRC1_COUNT_S 0 -#define FRC1_COUNT_DATA_MSB 22 -#define FRC1_COUNT_DATA_LSB 0 -#define FRC1_COUNT_DATA_MASK 0x007fffff - -#define FRC1_CTRL_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x8) -#define TIMER_FRC1_INT (BIT(8)) -#define TIMER_FRC1_CTRL 0x000000FF -#define TIMER_FRC1_CTRL_S 0 -#define FRC1_CTRL_DATA_MSB 7 -#define FRC1_CTRL_DATA_LSB 0 -#define FRC1_CTRL_DATA_MASK 0x000000ff - -#define FRC1_INT_ADDRESS (PERIPHS_TIMER_BASEDDR + 0xC) -#define TIMER_FRC1_INT_CLR_MASK (BIT(0)) -#define FRC1_INT_CLR_MSB 0 -#define FRC1_INT_CLR_LSB 0 -#define FRC1_INT_CLR_MASK 0x00000001 - -#define FRC2_LOAD_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x20) -#define TIMER_FRC2_LOAD_VALUE 0xFFFFFFFF -#define TIMER_FRC2_LOAD_VALUE_S 0 -#define FRC2_LOAD_DATA_MSB 31 -#define FRC2_LOAD_DATA_LSB 0 -#define FRC2_LOAD_DATA_MASK 0xffffffff - -#define FRC2_COUNT_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x24) -#define TIMER_FRC2_COUNT 0xFFFFFFFF -#define TIMER_FRC2_COUNT_S 0 -#define FRC2_COUNT_DATA_MSB 31 -#define FRC2_COUNT_DATA_LSB 0 -#define FRC2_COUNT_DATA_MASK 0xffffffff - -#define FRC2_CTRL_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x28) -#define TIMER_FRC2_INT (BIT(8)) -#define TIMER_FRC2_CTRL 0x000000FF -#define TIMER_FRC2_CTRL_S 0 -#define FRC2_CTRL_DATA_MSB 7 -#define FRC2_CTRL_DATA_LSB 0 -#define FRC2_CTRL_DATA_MASK 0x000000ff - -#define FRC2_INT_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x2C) -#define TIMER_FRC2_INT_CLR_MASK (BIT(0)) -#define FRC2_INT_CLR_MSB 0 -#define FRC2_INT_CLR_LSB 0 -#define FRC2_INT_CLR_MASK 0x00000001 - -#define FRC2_ALARM_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x30) -#define TIMER_FRC2_ALARM 0xFFFFFFFF -#define TIMER_FRC2_ALARM_S 0 -#define FRC2_ALARM_DATA_MSB 31 -#define FRC2_ALARM_DATA_LSB 0 -#define FRC2_ALARM_DATA_MASK 0xffffffff - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 _TIMER_REGISTER_H_ +#define _TIMER_REGISTER_H_ + +#define PERIPHS_TIMER_BASEDDR 0x60000600 + +#define FRC1_LOAD_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x0) +#define TIMER_FRC1_LOAD_VALUE 0x007FFFFF +#define TIMER_FRC1_LOAD_VALUE_S 0 +#define FRC1_LOAD_DATA_MSB 22 +#define FRC1_LOAD_DATA_LSB 0 +#define FRC1_LOAD_DATA_MASK 0x007fffff + +#define FRC1_COUNT_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x4) +#define TIMER_FRC1_COUNT 0x007FFFFF +#define TIMER_FRC1_COUNT_S 0 +#define FRC1_COUNT_DATA_MSB 22 +#define FRC1_COUNT_DATA_LSB 0 +#define FRC1_COUNT_DATA_MASK 0x007fffff + +#define FRC1_CTRL_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x8) +#define TIMER_FRC1_INT (BIT(8)) +#define TIMER_FRC1_CTRL 0x000000FF +#define TIMER_FRC1_CTRL_S 0 +#define FRC1_CTRL_DATA_MSB 7 +#define FRC1_CTRL_DATA_LSB 0 +#define FRC1_CTRL_DATA_MASK 0x000000ff + +#define FRC1_INT_ADDRESS (PERIPHS_TIMER_BASEDDR + 0xC) +#define TIMER_FRC1_INT_CLR_MASK (BIT(0)) +#define FRC1_INT_CLR_MSB 0 +#define FRC1_INT_CLR_LSB 0 +#define FRC1_INT_CLR_MASK 0x00000001 + +#define FRC2_LOAD_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x20) +#define TIMER_FRC2_LOAD_VALUE 0xFFFFFFFF +#define TIMER_FRC2_LOAD_VALUE_S 0 +#define FRC2_LOAD_DATA_MSB 31 +#define FRC2_LOAD_DATA_LSB 0 +#define FRC2_LOAD_DATA_MASK 0xffffffff + +#define FRC2_COUNT_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x24) +#define TIMER_FRC2_COUNT 0xFFFFFFFF +#define TIMER_FRC2_COUNT_S 0 +#define FRC2_COUNT_DATA_MSB 31 +#define FRC2_COUNT_DATA_LSB 0 +#define FRC2_COUNT_DATA_MASK 0xffffffff + +#define FRC2_CTRL_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x28) +#define TIMER_FRC2_INT (BIT(8)) +#define TIMER_FRC2_CTRL 0x000000FF +#define TIMER_FRC2_CTRL_S 0 +#define FRC2_CTRL_DATA_MSB 7 +#define FRC2_CTRL_DATA_LSB 0 +#define FRC2_CTRL_DATA_MASK 0x000000ff + +#define FRC2_INT_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x2C) +#define TIMER_FRC2_INT_CLR_MASK (BIT(0)) +#define FRC2_INT_CLR_MSB 0 +#define FRC2_INT_CLR_LSB 0 +#define FRC2_INT_CLR_MASK 0x00000001 + +#define FRC2_ALARM_ADDRESS (PERIPHS_TIMER_BASEDDR + 0x30) +#define TIMER_FRC2_ALARM 0xFFFFFFFF +#define TIMER_FRC2_ALARM_S 0 +#define FRC2_ALARM_DATA_MSB 31 +#define FRC2_ALARM_DATA_LSB 0 +#define FRC2_ALARM_DATA_MASK 0xffffffff + +#endif diff --git a/include/espressif/esp8266/uart_register.h b/include/espressif/esp8266/uart_register.h index a6a1a2a1..1beda316 100644 --- a/include/espressif/esp8266/uart_register.h +++ b/include/espressif/esp8266/uart_register.h @@ -1,154 +1,154 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 UART_REGISTER_H_ -#define UART_REGISTER_H_ - -#define REG_UART_BASE(i) (0x60000000 + (i)*0xf00) -//version value:32'h062000 - -#define UART_FIFO(i) (REG_UART_BASE(i) + 0x0) -#define UART_RXFIFO_RD_BYTE 0x000000FF -#define UART_RXFIFO_RD_BYTE_S 0 - -#define UART_INT_RAW(i) (REG_UART_BASE(i) + 0x4) -#define UART_RXFIFO_TOUT_INT_RAW (BIT(8)) -#define UART_BRK_DET_INT_RAW (BIT(7)) -#define UART_CTS_CHG_INT_RAW (BIT(6)) -#define UART_DSR_CHG_INT_RAW (BIT(5)) -#define UART_RXFIFO_OVF_INT_RAW (BIT(4)) -#define UART_FRM_ERR_INT_RAW (BIT(3)) -#define UART_PARITY_ERR_INT_RAW (BIT(2)) -#define UART_TXFIFO_EMPTY_INT_RAW (BIT(1)) -#define UART_RXFIFO_FULL_INT_RAW (BIT(0)) - -#define UART_INT_ST(i) (REG_UART_BASE(i) + 0x8) -#define UART_RXFIFO_TOUT_INT_ST (BIT(8)) -#define UART_BRK_DET_INT_ST (BIT(7)) -#define UART_CTS_CHG_INT_ST (BIT(6)) -#define UART_DSR_CHG_INT_ST (BIT(5)) -#define UART_RXFIFO_OVF_INT_ST (BIT(4)) -#define UART_FRM_ERR_INT_ST (BIT(3)) -#define UART_PARITY_ERR_INT_ST (BIT(2)) -#define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) -#define UART_RXFIFO_FULL_INT_ST (BIT(0)) - -#define UART_INT_ENA(i) (REG_UART_BASE(i) + 0xC) -#define UART_RXFIFO_TOUT_INT_ENA (BIT(8)) -#define UART_BRK_DET_INT_ENA (BIT(7)) -#define UART_CTS_CHG_INT_ENA (BIT(6)) -#define UART_DSR_CHG_INT_ENA (BIT(5)) -#define UART_RXFIFO_OVF_INT_ENA (BIT(4)) -#define UART_FRM_ERR_INT_ENA (BIT(3)) -#define UART_PARITY_ERR_INT_ENA (BIT(2)) -#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) -#define UART_RXFIFO_FULL_INT_ENA (BIT(0)) - -#define UART_INT_CLR(i) (REG_UART_BASE(i) + 0x10) -#define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) -#define UART_BRK_DET_INT_CLR (BIT(7)) -#define UART_CTS_CHG_INT_CLR (BIT(6)) -#define UART_DSR_CHG_INT_CLR (BIT(5)) -#define UART_RXFIFO_OVF_INT_CLR (BIT(4)) -#define UART_FRM_ERR_INT_CLR (BIT(3)) -#define UART_PARITY_ERR_INT_CLR (BIT(2)) -#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) -#define UART_RXFIFO_FULL_INT_CLR (BIT(0)) - -#define UART_CLKDIV(i) (REG_UART_BASE(i) + 0x14) -#define UART_CLKDIV_CNT 0x000FFFFF -#define UART_CLKDIV_S 0 - -#define UART_AUTOBAUD(i) (REG_UART_BASE(i) + 0x18) -#define UART_GLITCH_FILT 0x000000FF -#define UART_GLITCH_FILT_S 8 -#define UART_AUTOBAUD_EN (BIT(0)) - -#define UART_STATUS(i) (REG_UART_BASE(i) + 0x1C) -#define UART_TXD (BIT(31)) -#define UART_RTSN (BIT(30)) -#define UART_DTRN (BIT(29)) -#define UART_TXFIFO_CNT 0x000000FF -#define UART_TXFIFO_CNT_S 16 -#define UART_RXD (BIT(15)) -#define UART_CTSN (BIT(14)) -#define UART_DSRN (BIT(13)) -#define UART_RXFIFO_CNT 0x000000FF -#define UART_RXFIFO_CNT_S 0 - -#define UART_CONF0(i) (REG_UART_BASE(i) + 0x20) -#define UART_DTR_INV (BIT(24)) -#define UART_RTS_INV (BIT(23)) -#define UART_TXD_INV (BIT(22)) -#define UART_DSR_INV (BIT(21)) -#define UART_CTS_INV (BIT(20)) -#define UART_RXD_INV (BIT(19)) -#define UART_TXFIFO_RST (BIT(18)) -#define UART_RXFIFO_RST (BIT(17)) -#define UART_IRDA_EN (BIT(16)) -#define UART_TX_FLOW_EN (BIT(15)) -#define UART_LOOPBACK (BIT(14)) -#define UART_IRDA_RX_INV (BIT(13)) -#define UART_IRDA_TX_INV (BIT(12)) -#define UART_IRDA_WCTL (BIT(11)) -#define UART_IRDA_TX_EN (BIT(10)) -#define UART_IRDA_DPLX (BIT(9)) -#define UART_TXD_BRK (BIT(8)) -#define UART_SW_DTR (BIT(7)) -#define UART_SW_RTS (BIT(6)) -#define UART_STOP_BIT_NUM 0x00000003 -#define UART_STOP_BIT_NUM_S 4 -#define UART_BIT_NUM 0x00000003 -#define UART_BIT_NUM_S 2 -#define UART_PARITY_EN (BIT(1)) -#define UART_PARITY (BIT(0)) - -#define UART_CONF1(i) (REG_UART_BASE(i) + 0x24) -#define UART_RX_TOUT_EN (BIT(31)) -#define UART_RX_TOUT_THRHD 0x0000007F -#define UART_RX_TOUT_THRHD_S 24 -#define UART_RX_FLOW_EN (BIT(23)) -#define UART_RX_FLOW_THRHD 0x0000007F -#define UART_RX_FLOW_THRHD_S 16 -#define UART_TXFIFO_EMPTY_THRHD 0x0000007F -#define UART_TXFIFO_EMPTY_THRHD_S 8 -#define UART_RXFIFO_FULL_THRHD 0x0000007F -#define UART_RXFIFO_FULL_THRHD_S 0 - -#define UART_LOWPULSE(i) (REG_UART_BASE(i) + 0x28) -#define UART_LOWPULSE_MIN_CNT 0x000FFFFF -#define UART_LOWPULSE_MIN_CNT_S 0 - -#define UART_HIGHPULSE(i) (REG_UART_BASE(i) + 0x2C) -#define UART_HIGHPULSE_MIN_CNT 0x000FFFFF -#define UART_HIGHPULSE_MIN_CNT_S 0 - -#define UART_PULSE_NUM(i) (REG_UART_BASE(i) + 0x30) -#define UART_PULSE_NUM_CNT 0x0003FF -#define UART_PULSE_NUM_CNT_S 0 - -#define UART_DATE(i) (REG_UART_BASE(i) + 0x78) -#define UART_ID(i) (REG_UART_BASE(i) + 0x7C) - -#endif // UART_REGISTER_H_INCLUDED +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 UART_REGISTER_H_ +#define UART_REGISTER_H_ + +#define REG_UART_BASE(i) (0x60000000 + (i)*0xf00) +//version value:32'h062000 + +#define UART_FIFO(i) (REG_UART_BASE(i) + 0x0) +#define UART_RXFIFO_RD_BYTE 0x000000FF +#define UART_RXFIFO_RD_BYTE_S 0 + +#define UART_INT_RAW(i) (REG_UART_BASE(i) + 0x4) +#define UART_RXFIFO_TOUT_INT_RAW (BIT(8)) +#define UART_BRK_DET_INT_RAW (BIT(7)) +#define UART_CTS_CHG_INT_RAW (BIT(6)) +#define UART_DSR_CHG_INT_RAW (BIT(5)) +#define UART_RXFIFO_OVF_INT_RAW (BIT(4)) +#define UART_FRM_ERR_INT_RAW (BIT(3)) +#define UART_PARITY_ERR_INT_RAW (BIT(2)) +#define UART_TXFIFO_EMPTY_INT_RAW (BIT(1)) +#define UART_RXFIFO_FULL_INT_RAW (BIT(0)) + +#define UART_INT_ST(i) (REG_UART_BASE(i) + 0x8) +#define UART_RXFIFO_TOUT_INT_ST (BIT(8)) +#define UART_BRK_DET_INT_ST (BIT(7)) +#define UART_CTS_CHG_INT_ST (BIT(6)) +#define UART_DSR_CHG_INT_ST (BIT(5)) +#define UART_RXFIFO_OVF_INT_ST (BIT(4)) +#define UART_FRM_ERR_INT_ST (BIT(3)) +#define UART_PARITY_ERR_INT_ST (BIT(2)) +#define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) +#define UART_RXFIFO_FULL_INT_ST (BIT(0)) + +#define UART_INT_ENA(i) (REG_UART_BASE(i) + 0xC) +#define UART_RXFIFO_TOUT_INT_ENA (BIT(8)) +#define UART_BRK_DET_INT_ENA (BIT(7)) +#define UART_CTS_CHG_INT_ENA (BIT(6)) +#define UART_DSR_CHG_INT_ENA (BIT(5)) +#define UART_RXFIFO_OVF_INT_ENA (BIT(4)) +#define UART_FRM_ERR_INT_ENA (BIT(3)) +#define UART_PARITY_ERR_INT_ENA (BIT(2)) +#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) +#define UART_RXFIFO_FULL_INT_ENA (BIT(0)) + +#define UART_INT_CLR(i) (REG_UART_BASE(i) + 0x10) +#define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) +#define UART_BRK_DET_INT_CLR (BIT(7)) +#define UART_CTS_CHG_INT_CLR (BIT(6)) +#define UART_DSR_CHG_INT_CLR (BIT(5)) +#define UART_RXFIFO_OVF_INT_CLR (BIT(4)) +#define UART_FRM_ERR_INT_CLR (BIT(3)) +#define UART_PARITY_ERR_INT_CLR (BIT(2)) +#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) +#define UART_RXFIFO_FULL_INT_CLR (BIT(0)) + +#define UART_CLKDIV(i) (REG_UART_BASE(i) + 0x14) +#define UART_CLKDIV_CNT 0x000FFFFF +#define UART_CLKDIV_S 0 + +#define UART_AUTOBAUD(i) (REG_UART_BASE(i) + 0x18) +#define UART_GLITCH_FILT 0x000000FF +#define UART_GLITCH_FILT_S 8 +#define UART_AUTOBAUD_EN (BIT(0)) + +#define UART_STATUS(i) (REG_UART_BASE(i) + 0x1C) +#define UART_TXD (BIT(31)) +#define UART_RTSN (BIT(30)) +#define UART_DTRN (BIT(29)) +#define UART_TXFIFO_CNT 0x000000FF +#define UART_TXFIFO_CNT_S 16 +#define UART_RXD (BIT(15)) +#define UART_CTSN (BIT(14)) +#define UART_DSRN (BIT(13)) +#define UART_RXFIFO_CNT 0x000000FF +#define UART_RXFIFO_CNT_S 0 + +#define UART_CONF0(i) (REG_UART_BASE(i) + 0x20) +#define UART_DTR_INV (BIT(24)) +#define UART_RTS_INV (BIT(23)) +#define UART_TXD_INV (BIT(22)) +#define UART_DSR_INV (BIT(21)) +#define UART_CTS_INV (BIT(20)) +#define UART_RXD_INV (BIT(19)) +#define UART_TXFIFO_RST (BIT(18)) +#define UART_RXFIFO_RST (BIT(17)) +#define UART_IRDA_EN (BIT(16)) +#define UART_TX_FLOW_EN (BIT(15)) +#define UART_LOOPBACK (BIT(14)) +#define UART_IRDA_RX_INV (BIT(13)) +#define UART_IRDA_TX_INV (BIT(12)) +#define UART_IRDA_WCTL (BIT(11)) +#define UART_IRDA_TX_EN (BIT(10)) +#define UART_IRDA_DPLX (BIT(9)) +#define UART_TXD_BRK (BIT(8)) +#define UART_SW_DTR (BIT(7)) +#define UART_SW_RTS (BIT(6)) +#define UART_STOP_BIT_NUM 0x00000003 +#define UART_STOP_BIT_NUM_S 4 +#define UART_BIT_NUM 0x00000003 +#define UART_BIT_NUM_S 2 +#define UART_PARITY_EN (BIT(1)) +#define UART_PARITY (BIT(0)) + +#define UART_CONF1(i) (REG_UART_BASE(i) + 0x24) +#define UART_RX_TOUT_EN (BIT(31)) +#define UART_RX_TOUT_THRHD 0x0000007F +#define UART_RX_TOUT_THRHD_S 24 +#define UART_RX_FLOW_EN (BIT(23)) +#define UART_RX_FLOW_THRHD 0x0000007F +#define UART_RX_FLOW_THRHD_S 16 +#define UART_TXFIFO_EMPTY_THRHD 0x0000007F +#define UART_TXFIFO_EMPTY_THRHD_S 8 +#define UART_RXFIFO_FULL_THRHD 0x0000007F +#define UART_RXFIFO_FULL_THRHD_S 0 + +#define UART_LOWPULSE(i) (REG_UART_BASE(i) + 0x28) +#define UART_LOWPULSE_MIN_CNT 0x000FFFFF +#define UART_LOWPULSE_MIN_CNT_S 0 + +#define UART_HIGHPULSE(i) (REG_UART_BASE(i) + 0x2C) +#define UART_HIGHPULSE_MIN_CNT 0x000FFFFF +#define UART_HIGHPULSE_MIN_CNT_S 0 + +#define UART_PULSE_NUM(i) (REG_UART_BASE(i) + 0x30) +#define UART_PULSE_NUM_CNT 0x0003FF +#define UART_PULSE_NUM_CNT_S 0 + +#define UART_DATE(i) (REG_UART_BASE(i) + 0x78) +#define UART_ID(i) (REG_UART_BASE(i) + 0x7C) + +#endif // UART_REGISTER_H_INCLUDED diff --git a/include/espressif/esp_common.h b/include/espressif/esp_common.h index 12df16de..7596201a 100644 --- a/include/espressif/esp_common.h +++ b/include/espressif/esp_common.h @@ -1,111 +1,111 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __ESP_COMMON_H__ -#define __ESP_COMMON_H__ - -/** \mainpage ESP8266_RTOS_SDK - * - * - Misc APIs : misc APIs - * - WiFi APIs : WiFi related APIs - * - SoftAP APIs : ESP8266 Soft-AP APIs - * - Station APIs : ESP8266 station APIs - * - Common APIs : WiFi common APIs - * - Force Sleep APIs : WiFi Force Sleep APIs - * - Rate Control APIs : WiFi Rate Control APIs - * - User IE APIs : WiFi User IE APIs - * - Sniffer APIs : WiFi sniffer APIs - * - WPS APIs : WiFi WPS APIs - * - Smartconfig APIs : SmartConfig APIs - * - AirKiss APIs : AirKiss APIs - * - Spiffs APIs : Spiffs APIs - * - SSC APIs : Simple Serial Command APIs - * - System APIs : System APIs - * - Boot APIs : Boot mode APIs - * - Upgrade APIs : Firmware upgrade (FOTA) APIs - * - Software timer APIs : Software timer APIs - * - Network Espconn APIs : Network espconn APIs - * - ESP-NOW APIs : ESP-NOW APIs - * - Mesh APIs : Mesh APIs - * - Driver APIs : Driver APIs - * - PWM Driver APIs : PWM driver APIs - * - UART Driver APIs : UART driver APIs - * - GPIO Driver APIs : GPIO driver APIs - * - SPI Driver APIs : SPI Flash APIs - * - Hardware timer APIs : Hardware timer APIs - * - * void user_init(void) is the entrance function of the application. - * @attention 1. It is recommended that users set the timer to the periodic mode - * for periodic checks. - * @attention (1). In freeRTOS timer or os_timer, do not delay by while(1) or - * in the manner that will block the thread. - * @attention (2). The timer callback should not occupy CPU more than 15ms. - * @attention (3). os_timer_t should not define a local variable, it has to be global varialbe - * or memory got by malloc. - * - * @attention 2. Since esp_iot_rtos_sdk_v1.0.4, functions are stored in CACHE by - * default, need not be added ICACHE_FLASH_ATTR any more. The interrupt - * functions can also be stored in CACHE. If users want to store some - * frequently called functions in RAM, please add IRAM_ATTR before - * functions' name. - * - * @attention 3. Network programming use socket, please do not bind to the same port. - * @attention (1). If users want to create 3 or more than 3 TCP connections, please add - * "TCP_WND = 2 x TCP_MSS;" in "user_init". - * - * @attention 4. Priority of the RTOS SDK is 15. xTaskCreate is an interface of - * freeRTOS. For details of the freeRTOS and APIs of the system, - * please visit http://www.freertos.org - * @attention (1). When using xTaskCreate to create a task, the task stack range is [176, 512]. - * @attention (2). If an array whose length is over 60 bytes is used in a task, - * it is suggested that users use malloc and free rather than local - * variable to allocate array. Large local variables could lead to - * task stack overflow. - * @attention (3). The RTOS SDK takes some priorities. Priority of the pp task is - * 13; priority of precise timer(ms) thread is 12; priority of the - * TCP/IP task is 10; priority of the freeRTOS timer is 2; priority of - * the idle task is 0. - * @attention (4). Users can use tasks with priorities from 1 to 9. - * @attention (5). Do not revise FreeRTOSConfig.h, configurations are decided by source code - * inside the RTOS SDK, users can not change it. - */ - -#include "c_types.h" -#include "esp_libc.h" -#include "esp_misc.h" -#include "esp_wifi.h" -#include "esp_softap.h" -#include "esp_sta.h" -#include "esp_system.h" -#include "esp_timer.h" -#include "esp_ssc.h" -#include "esp_spiffs.h" - -#include "esp8266/esp8266.h" - -#include "smartconfig.h" -#include "spi_flash.h" -#include "pwm.h" - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __ESP_COMMON_H__ +#define __ESP_COMMON_H__ + +/** \mainpage ESP8266_RTOS_SDK + * + * - Misc APIs : misc APIs + * - WiFi APIs : WiFi related APIs + * - SoftAP APIs : ESP8266 Soft-AP APIs + * - Station APIs : ESP8266 station APIs + * - Common APIs : WiFi common APIs + * - Force Sleep APIs : WiFi Force Sleep APIs + * - Rate Control APIs : WiFi Rate Control APIs + * - User IE APIs : WiFi User IE APIs + * - Sniffer APIs : WiFi sniffer APIs + * - WPS APIs : WiFi WPS APIs + * - Smartconfig APIs : SmartConfig APIs + * - AirKiss APIs : AirKiss APIs + * - Spiffs APIs : Spiffs APIs + * - SSC APIs : Simple Serial Command APIs + * - System APIs : System APIs + * - Boot APIs : Boot mode APIs + * - Upgrade APIs : Firmware upgrade (FOTA) APIs + * - Software timer APIs : Software timer APIs + * - Network Espconn APIs : Network espconn APIs + * - ESP-NOW APIs : ESP-NOW APIs + * - Mesh APIs : Mesh APIs + * - Driver APIs : Driver APIs + * - PWM Driver APIs : PWM driver APIs + * - UART Driver APIs : UART driver APIs + * - GPIO Driver APIs : GPIO driver APIs + * - SPI Driver APIs : SPI Flash APIs + * - Hardware timer APIs : Hardware timer APIs + * + * void user_init(void) is the entrance function of the application. + * @attention 1. It is recommended that users set the timer to the periodic mode + * for periodic checks. + * @attention (1). In freeRTOS timer or os_timer, do not delay by while(1) or + * in the manner that will block the thread. + * @attention (2). The timer callback should not occupy CPU more than 15ms. + * @attention (3). os_timer_t should not define a local variable, it has to be global varialbe + * or memory got by malloc. + * + * @attention 2. Since esp_iot_rtos_sdk_v1.0.4, functions are stored in CACHE by + * default, need not be added ICACHE_FLASH_ATTR any more. The interrupt + * functions can also be stored in CACHE. If users want to store some + * frequently called functions in RAM, please add IRAM_ATTR before + * functions' name. + * + * @attention 3. Network programming use socket, please do not bind to the same port. + * @attention (1). If users want to create 3 or more than 3 TCP connections, please add + * "TCP_WND = 2 x TCP_MSS;" in "user_init". + * + * @attention 4. Priority of the RTOS SDK is 15. xTaskCreate is an interface of + * freeRTOS. For details of the freeRTOS and APIs of the system, + * please visit http://www.freertos.org + * @attention (1). When using xTaskCreate to create a task, the task stack range is [176, 512]. + * @attention (2). If an array whose length is over 60 bytes is used in a task, + * it is suggested that users use malloc and free rather than local + * variable to allocate array. Large local variables could lead to + * task stack overflow. + * @attention (3). The RTOS SDK takes some priorities. Priority of the pp task is + * 13; priority of precise timer(ms) thread is 12; priority of the + * TCP/IP task is 10; priority of the freeRTOS timer is 2; priority of + * the idle task is 0. + * @attention (4). Users can use tasks with priorities from 1 to 9. + * @attention (5). Do not revise FreeRTOSConfig.h, configurations are decided by source code + * inside the RTOS SDK, users can not change it. + */ + +#include "c_types.h" +#include "esp_libc.h" +#include "esp_misc.h" +#include "esp_wifi.h" +#include "esp_softap.h" +#include "esp_sta.h" +#include "esp_system.h" +#include "esp_timer.h" +#include "esp_ssc.h" +#include "esp_spiffs.h" + +#include "esp8266/esp8266.h" + +#include "smartconfig.h" +#include "spi_flash.h" +#include "pwm.h" + +#endif diff --git a/include/espressif/esp_misc.h b/include/espressif/esp_misc.h index 177ee1e8..5f46d9f1 100644 --- a/include/espressif/esp_misc.h +++ b/include/espressif/esp_misc.h @@ -1,108 +1,108 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __ESP_MISC_H__ -#define __ESP_MISC_H__ - -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup Misc_APIs Misc APIs - * @brief misc APIs - */ - -/** @addtogroup Misc_APIs - * @{ - */ - -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" - -#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \ - ip4_addr2_16(ipaddr), \ - ip4_addr3_16(ipaddr), \ - ip4_addr4_16(ipaddr) - -#define IPSTR "%d.%d.%d.%d" - -/** - * @brief Delay function, maximum value: 65535 us. - * - * @param uint16 us : delay time, uint: us, maximum value: 65535 us - * - * @return null - */ -void os_delay_us(uint16 us); - -/** - * @brief Register the print output function. - * - * @attention os_install_putc1((void *)uart1_write_char) in uart_init will set - * printf to print from UART 1, otherwise, printf will start from - * UART 0 by default. - * - * @param void(*p)(char c) - pointer of print function - * - * @return null - */ -void os_install_putc1(void (*p)(char c)); - -/** - * @brief Print a character. Start from from UART0 by default. - * - * @param char c - character to be printed - * - * @return null - */ -void os_putc(char c); - -enum dhcp_status { - DHCP_STOPPED, /**< disable DHCP */ - DHCP_STARTED /**< enable DHCP */ -}; - -struct dhcps_lease { - bool enable; /**< enable DHCP lease or not */ - struct ip_addr start_ip; /**< start IP of IP range */ - struct ip_addr end_ip; /**< end IP of IP range */ -}; - -enum dhcps_offer_option { - OFFER_START = 0x00, /**< DHCP offer option start */ - OFFER_ROUTER = 0x01, /**< DHCP offer router, only support this option now */ - OFFER_END /**< DHCP offer option start */ -}; - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __ESP_MISC_H__ +#define __ESP_MISC_H__ + +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup Misc_APIs Misc APIs + * @brief misc APIs + */ + +/** @addtogroup Misc_APIs + * @{ + */ + +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" + +#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \ + ip4_addr2_16(ipaddr), \ + ip4_addr3_16(ipaddr), \ + ip4_addr4_16(ipaddr) + +#define IPSTR "%d.%d.%d.%d" + +/** + * @brief Delay function, maximum value: 65535 us. + * + * @param uint16 us : delay time, uint: us, maximum value: 65535 us + * + * @return null + */ +void os_delay_us(uint16 us); + +/** + * @brief Register the print output function. + * + * @attention os_install_putc1((void *)uart1_write_char) in uart_init will set + * printf to print from UART 1, otherwise, printf will start from + * UART 0 by default. + * + * @param void(*p)(char c) - pointer of print function + * + * @return null + */ +void os_install_putc1(void (*p)(char c)); + +/** + * @brief Print a character. Start from from UART0 by default. + * + * @param char c - character to be printed + * + * @return null + */ +void os_putc(char c); + +enum dhcp_status { + DHCP_STOPPED, /**< disable DHCP */ + DHCP_STARTED /**< enable DHCP */ +}; + +struct dhcps_lease { + bool enable; /**< enable DHCP lease or not */ + struct ip_addr start_ip; /**< start IP of IP range */ + struct ip_addr end_ip; /**< end IP of IP range */ +}; + +enum dhcps_offer_option { + OFFER_START = 0x00, /**< DHCP offer option start */ + OFFER_ROUTER = 0x01, /**< DHCP offer router, only support this option now */ + OFFER_END /**< DHCP offer option start */ +}; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/espressif/esp_softap.h b/include/espressif/esp_softap.h index 962b9ec8..38810ea2 100644 --- a/include/espressif/esp_softap.h +++ b/include/espressif/esp_softap.h @@ -1,290 +1,290 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __ESP_SOFTAP_H__ -#define __ESP_SOFTAP_H__ - -#include "queue.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup WiFi_APIs WiFi Related APIs - * @brief WiFi APIs - */ - -/** @addtogroup WiFi_APIs - * @{ - */ - -/** \defgroup SoftAP_APIs SoftAP APIs - * @brief ESP8266 Soft-AP APIs - * @attention To call APIs related to ESP8266 soft-AP has to enable soft-AP mode first (wifi_set_opmode) - */ - -/** @addtogroup SoftAP_APIs - * @{ - */ - -struct softap_config { - uint8 ssid[32]; /**< SSID of ESP8266 soft-AP */ - uint8 password[64]; /**< Password of ESP8266 soft-AP */ - uint8 ssid_len; /**< Length of SSID. If softap_config.ssid_len==0, check the SSID until there is a termination character; otherwise, set the SSID length according to softap_config.ssid_len. */ - uint8 channel; /**< Channel of ESP8266 soft-AP */ - AUTH_MODE authmode; /**< Auth mode of ESP8266 soft-AP. Do not support AUTH_WEP in soft-AP mode */ - uint8 ssid_hidden; /**< Broadcast SSID or not, default 0, broadcast the SSID */ - uint8 max_connection; /**< Max number of stations allowed to connect in, default 4, max 4 */ - uint16 beacon_interval; /**< Beacon interval, 100 ~ 60000 ms, default 100 */ -}; - -struct station_info { - STAILQ_ENTRY(station_info) next; /**< Information of next AP */ - - uint8 bssid[6]; /**< BSSID of AP */ - struct ip_addr ip; /**< IP address of AP */ -}; - -/** - * @brief Get the current configuration of the ESP8266 WiFi soft-AP - * - * @param struct softap_config *config : ESP8266 soft-AP configuration - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_get_config(struct softap_config *config); - -/** - * @brief Get the configuration of the ESP8266 WiFi soft-AP saved in the flash - * - * @param struct softap_config *config : ESP8266 soft-AP configuration - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_get_config_default(struct softap_config *config); - -/** - * @brief Set the configuration of the WiFi soft-AP and save it to the Flash. - * - * @attention 1. This configuration will be saved in flash system parameter area if changed - * @attention 2. The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, - * the soft-AP will adjust its channel automatically to be the same as - * the channel of the ESP8266 station. - * - * @param struct softap_config *config : ESP8266 soft-AP configuration - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_set_config(struct softap_config *config); - -/** - * @brief Set the configuration of the WiFi soft-AP; the configuration will - * not be saved to the Flash. - * - * @attention The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, - * the soft-AP will adjust its channel automatically to be the same as - * the channel of the ESP8266 station. - * - * @param struct softap_config *config : ESP8266 soft-AP configuration - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_set_config_current(struct softap_config *config); - -/** - * @brief Get the number of stations connected to the ESP8266 soft-AP. - * - * @attention The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, - * the soft-AP will adjust its channel automatically to be the same as - * the channel of the ESP8266 station. - * - * @param null - * - * @return the number of stations connected to the ESP8266 soft-AP - */ -uint8 wifi_softap_get_station_num(void); - -/** - * @brief Get the information of stations connected to the ESP8266 soft-AP, - * including MAC and IP. - * - * @attention wifi_softap_get_station_info depends on DHCP, it can only - * be used when DHCP is enabled, so it can not get the static IP. - * - * @param null - * - * @return struct station_info* : station information structure - */ -struct station_info *wifi_softap_get_station_info(void); - -/** - * @brief Free the space occupied by station_info when wifi_softap_get_station_info is called. - * - * @attention The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, - * the soft-AP will adjust its channel automatically to be the same as - * the channel of the ESP8266 station. - * - * @param null - * - * @return null - */ -void wifi_softap_free_station_info(void); - -/** - * @brief Enable the ESP8266 soft-AP DHCP server. - * - * @attention 1. The DHCP is enabled by default. - * @attention 2. The DHCP and the static IP related API (wifi_set_ip_info) influence - * each other, if the DHCP is enabled, the static IP will be disabled; - * if the static IP is enabled, the DHCP will be disabled. - * It depends on the latest configuration. - * - * @param null - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_dhcps_start(void); - -/** - * @brief Disable the ESP8266 soft-AP DHCP server. The DHCP is enabled by default. - * - * @param null - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_dhcps_stop(void); - -/** - * @brief Get the ESP8266 soft-AP DHCP server status. - * - * @param null - * - * @return enum dhcp_status - */ -enum dhcp_status wifi_softap_dhcps_status(void); - -/** - * @brief Query the IP range that can be got from the ESP8266 soft-AP DHCP server. - * - * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. - * - * @param struct dhcps_lease *please : IP range of the ESP8266 soft-AP DHCP server. - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_get_dhcps_lease(struct dhcps_lease *please); - -/** - * @brief Set the IP range of the ESP8266 soft-AP DHCP server. - * - * @attention 1. The IP range should be in the same sub-net with the ESP8266 - * soft-AP IP address. - * @attention 2. This API should only be called when the DHCP server is disabled - * (wifi_softap_dhcps_stop). - * @attention 3. This configuration will only take effect the next time when the - * DHCP server is enabled (wifi_softap_dhcps_start). - * - If the DHCP server is disabled again, this API should be called to set the IP range. - * - Otherwise, when the DHCP server is enabled later, the default IP range will be used. - * - * @param struct dhcps_lease *please : IP range of the ESP8266 soft-AP DHCP server. - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please); - -/** - * @brief Get ESP8266 soft-AP DHCP server lease time. - * - * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. - * - * @param null - * - * @return lease time, uint: minute. - */ -uint32 wifi_softap_get_dhcps_lease_time(void); - -/** - * @brief Set ESP8266 soft-AP DHCP server lease time, default is 120 minutes. - * - * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. - * - * @param uint32 minute : lease time, uint: minute, range:[1, 2880]. - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_set_dhcps_lease_time(uint32 minute); - -/** - * @brief Reset ESP8266 soft-AP DHCP server lease time which is 120 minutes by default. - * - * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. - * - * @param null - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_reset_dhcps_lease_time(void); - -/** - * @brief Set the ESP8266 soft-AP DHCP server option. - * - * Example: - *
 
-  *         uint8 mode = 0;
-  *         wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, &mode);
-  * 
- * - * @param uint8 level : OFFER_ROUTER, set the router option. - * @param void* optarg : - * - bit0, 0 disable the router information; - * - bit0, 1 enable the router information. - * - * @return true : succeed - * @return false : fail - */ -bool wifi_softap_set_dhcps_offer_option(uint8 level, void *optarg); - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __ESP_SOFTAP_H__ +#define __ESP_SOFTAP_H__ + +#include "queue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup SoftAP_APIs SoftAP APIs + * @brief ESP8266 Soft-AP APIs + * @attention To call APIs related to ESP8266 soft-AP has to enable soft-AP mode first (wifi_set_opmode) + */ + +/** @addtogroup SoftAP_APIs + * @{ + */ + +struct softap_config { + uint8 ssid[32]; /**< SSID of ESP8266 soft-AP */ + uint8 password[64]; /**< Password of ESP8266 soft-AP */ + uint8 ssid_len; /**< Length of SSID. If softap_config.ssid_len==0, check the SSID until there is a termination character; otherwise, set the SSID length according to softap_config.ssid_len. */ + uint8 channel; /**< Channel of ESP8266 soft-AP */ + AUTH_MODE authmode; /**< Auth mode of ESP8266 soft-AP. Do not support AUTH_WEP in soft-AP mode */ + uint8 ssid_hidden; /**< Broadcast SSID or not, default 0, broadcast the SSID */ + uint8 max_connection; /**< Max number of stations allowed to connect in, default 4, max 4 */ + uint16 beacon_interval; /**< Beacon interval, 100 ~ 60000 ms, default 100 */ +}; + +struct station_info { + STAILQ_ENTRY(station_info) next; /**< Information of next AP */ + + uint8 bssid[6]; /**< BSSID of AP */ + struct ip_addr ip; /**< IP address of AP */ +}; + +/** + * @brief Get the current configuration of the ESP8266 WiFi soft-AP + * + * @param struct softap_config *config : ESP8266 soft-AP configuration + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_get_config(struct softap_config *config); + +/** + * @brief Get the configuration of the ESP8266 WiFi soft-AP saved in the flash + * + * @param struct softap_config *config : ESP8266 soft-AP configuration + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_get_config_default(struct softap_config *config); + +/** + * @brief Set the configuration of the WiFi soft-AP and save it to the Flash. + * + * @attention 1. This configuration will be saved in flash system parameter area if changed + * @attention 2. The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, + * the soft-AP will adjust its channel automatically to be the same as + * the channel of the ESP8266 station. + * + * @param struct softap_config *config : ESP8266 soft-AP configuration + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_set_config(struct softap_config *config); + +/** + * @brief Set the configuration of the WiFi soft-AP; the configuration will + * not be saved to the Flash. + * + * @attention The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, + * the soft-AP will adjust its channel automatically to be the same as + * the channel of the ESP8266 station. + * + * @param struct softap_config *config : ESP8266 soft-AP configuration + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_set_config_current(struct softap_config *config); + +/** + * @brief Get the number of stations connected to the ESP8266 soft-AP. + * + * @attention The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, + * the soft-AP will adjust its channel automatically to be the same as + * the channel of the ESP8266 station. + * + * @param null + * + * @return the number of stations connected to the ESP8266 soft-AP + */ +uint8 wifi_softap_get_station_num(void); + +/** + * @brief Get the information of stations connected to the ESP8266 soft-AP, + * including MAC and IP. + * + * @attention wifi_softap_get_station_info depends on DHCP, it can only + * be used when DHCP is enabled, so it can not get the static IP. + * + * @param null + * + * @return struct station_info* : station information structure + */ +struct station_info *wifi_softap_get_station_info(void); + +/** + * @brief Free the space occupied by station_info when wifi_softap_get_station_info is called. + * + * @attention The ESP8266 is limited to only one channel, so when in the soft-AP+station mode, + * the soft-AP will adjust its channel automatically to be the same as + * the channel of the ESP8266 station. + * + * @param null + * + * @return null + */ +void wifi_softap_free_station_info(void); + +/** + * @brief Enable the ESP8266 soft-AP DHCP server. + * + * @attention 1. The DHCP is enabled by default. + * @attention 2. The DHCP and the static IP related API (wifi_set_ip_info) influence + * each other, if the DHCP is enabled, the static IP will be disabled; + * if the static IP is enabled, the DHCP will be disabled. + * It depends on the latest configuration. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_dhcps_start(void); + +/** + * @brief Disable the ESP8266 soft-AP DHCP server. The DHCP is enabled by default. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_dhcps_stop(void); + +/** + * @brief Get the ESP8266 soft-AP DHCP server status. + * + * @param null + * + * @return enum dhcp_status + */ +enum dhcp_status wifi_softap_dhcps_status(void); + +/** + * @brief Query the IP range that can be got from the ESP8266 soft-AP DHCP server. + * + * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. + * + * @param struct dhcps_lease *please : IP range of the ESP8266 soft-AP DHCP server. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_get_dhcps_lease(struct dhcps_lease *please); + +/** + * @brief Set the IP range of the ESP8266 soft-AP DHCP server. + * + * @attention 1. The IP range should be in the same sub-net with the ESP8266 + * soft-AP IP address. + * @attention 2. This API should only be called when the DHCP server is disabled + * (wifi_softap_dhcps_stop). + * @attention 3. This configuration will only take effect the next time when the + * DHCP server is enabled (wifi_softap_dhcps_start). + * - If the DHCP server is disabled again, this API should be called to set the IP range. + * - Otherwise, when the DHCP server is enabled later, the default IP range will be used. + * + * @param struct dhcps_lease *please : IP range of the ESP8266 soft-AP DHCP server. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please); + +/** + * @brief Get ESP8266 soft-AP DHCP server lease time. + * + * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. + * + * @param null + * + * @return lease time, uint: minute. + */ +uint32 wifi_softap_get_dhcps_lease_time(void); + +/** + * @brief Set ESP8266 soft-AP DHCP server lease time, default is 120 minutes. + * + * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. + * + * @param uint32 minute : lease time, uint: minute, range:[1, 2880]. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_set_dhcps_lease_time(uint32 minute); + +/** + * @brief Reset ESP8266 soft-AP DHCP server lease time which is 120 minutes by default. + * + * @attention This API can only be called during ESP8266 soft-AP DHCP server enabled. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_reset_dhcps_lease_time(void); + +/** + * @brief Set the ESP8266 soft-AP DHCP server option. + * + * Example: + *
 
+  *         uint8 mode = 0;
+  *         wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, &mode);
+  * 
+ * + * @param uint8 level : OFFER_ROUTER, set the router option. + * @param void* optarg : + * - bit0, 0 disable the router information; + * - bit0, 1 enable the router information. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_softap_set_dhcps_offer_option(uint8 level, void *optarg); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/espressif/esp_spiffs.h b/include/espressif/esp_spiffs.h index 2d83a5be..87585a03 100644 --- a/include/espressif/esp_spiffs.h +++ b/include/espressif/esp_spiffs.h @@ -1,84 +1,84 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __ESP_SPIFFS_H__ -#define __ESP_SPIFFS_H__ - -#include "spiffs/spiffs.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup Spiffs_APIs Spiffs APIs - * @brief Spiffs APIs - * - * More details about spiffs on https://github.com/pellepl/spiffs - * - */ - -/** @addtogroup Spiffs_APIs - * @{ - */ - -struct esp_spiffs_config { - uint32 phys_size; /**< physical size of the SPI Flash */ - uint32 phys_addr; /**< physical offset in spi flash used for spiffs, must be on block boundary */ - uint32 phys_erase_block; /**< physical size when erasing a block */ - - uint32 log_block_size; /**< logical size of a block, must be on physical block size boundary and must never be less than a physical block */ - uint32 log_page_size; /**< logical size of a page, at least log_block_size/8 */ - - uint32 fd_buf_size; /**< file descriptor memory area size */ - uint32 cache_buf_size; /**< cache buffer size */ -}; - -/** - * @brief Initialize spiffs - * - * @param struct esp_spiffs_config *config : ESP8266 spiffs configuration - * - * @return 0 : succeed - * @return otherwise : fail - */ -sint32 esp_spiffs_init(struct esp_spiffs_config *config); - -/** - * @brief Deinitialize spiffs - * - * @param uint8 format : 0, only deinit; otherwise, deinit spiffs and format. - * - * @return null - */ -void esp_spiffs_deinit(uint8 format); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ESP_SPIFFS_H__ */ +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __ESP_SPIFFS_H__ +#define __ESP_SPIFFS_H__ + +#include "spiffs/spiffs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup Spiffs_APIs Spiffs APIs + * @brief Spiffs APIs + * + * More details about spiffs on https://github.com/pellepl/spiffs + * + */ + +/** @addtogroup Spiffs_APIs + * @{ + */ + +struct esp_spiffs_config { + uint32 phys_size; /**< physical size of the SPI Flash */ + uint32 phys_addr; /**< physical offset in spi flash used for spiffs, must be on block boundary */ + uint32 phys_erase_block; /**< physical size when erasing a block */ + + uint32 log_block_size; /**< logical size of a block, must be on physical block size boundary and must never be less than a physical block */ + uint32 log_page_size; /**< logical size of a page, at least log_block_size/8 */ + + uint32 fd_buf_size; /**< file descriptor memory area size */ + uint32 cache_buf_size; /**< cache buffer size */ +}; + +/** + * @brief Initialize spiffs + * + * @param struct esp_spiffs_config *config : ESP8266 spiffs configuration + * + * @return 0 : succeed + * @return otherwise : fail + */ +sint32 esp_spiffs_init(struct esp_spiffs_config *config); + +/** + * @brief Deinitialize spiffs + * + * @param uint8 format : 0, only deinit; otherwise, deinit spiffs and format. + * + * @return null + */ +void esp_spiffs_deinit(uint8 format); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_SPIFFS_H__ */ diff --git a/include/espressif/esp_ssc.h b/include/espressif/esp_ssc.h index a214566a..50a16640 100644 --- a/include/espressif/esp_ssc.h +++ b/include/espressif/esp_ssc.h @@ -1,125 +1,125 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __ESP_SSC_H__ -#define __ESP_SSC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#define CMD_T_ASYNC 0x01 -#define CMD_T_SYNC 0x02 - -typedef struct cmd_s { - char *cmd_str; - uint8 flag; - uint8 id; - void (* cmd_func)(void); - void (* cmd_callback)(void *arg); -} ssc_cmd_t; - -#define MAX_LINE_N 127 - -typedef enum { - SSC_BR_9600 = 9600, - SSC_BR_19200 = 19200, - SSC_BR_38400 = 38400, - SSC_BR_57600 = 57600, - SSC_BR_74880 = 74880, - SSC_BR_115200 = 115200, - SSC_BR_230400 = 230400, - SSC_BR_460800 = 460800, - SSC_BR_921600 = 921600 -} SscBaudRate; - -/** \defgroup SSC_APIs SSC APIs - * @brief SSC APIs - * - * SSC means simple serial command. - * SSC APIs allows users to define their own command, users can refer to spiffs_test/test_main.c. - * - */ - -/** @addtogroup SSC_APIs - * @{ - */ - -/** - * @brief Initial the ssc function. - * - * @param SscBaudRate bandrate : baud rate - * - * @return null - */ -void ssc_attach(SscBaudRate bandrate); - -/** - * @brief Get the length of the simple serial command. - * - * @param null - * - * @return length of the command. - */ -int ssc_param_len(void); - -/** - * @brief Get the simple serial command string. - * - * @param null - * - * @return the command. - */ -char *ssc_param_str(void); - -/** - * @brief Parse the simple serial command (ssc). - * - * @param char *pLine : [input] the ssc string - * @param char *argv[] : [output] parameters of the ssc - * - * @return the number of parameters. - */ -int ssc_parse_param(char *pLine, char *argv[]); - -/** - * @brief Register the user-defined simple serial command (ssc) set. - * - * @param ssc_cmd_t *cmdset : the ssc set - * @param uint8 cmdnum : number of commands - * @param void (* help)(void) : callback of user-guide - * - * @return null - */ -void ssc_register(ssc_cmd_t *cmdset, uint8 cmdnum, void (* help)(void)); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ESP_SSC_H__ */ +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __ESP_SSC_H__ +#define __ESP_SSC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define CMD_T_ASYNC 0x01 +#define CMD_T_SYNC 0x02 + +typedef struct cmd_s { + char *cmd_str; + uint8 flag; + uint8 id; + void (* cmd_func)(void); + void (* cmd_callback)(void *arg); +} ssc_cmd_t; + +#define MAX_LINE_N 127 + +typedef enum { + SSC_BR_9600 = 9600, + SSC_BR_19200 = 19200, + SSC_BR_38400 = 38400, + SSC_BR_57600 = 57600, + SSC_BR_74880 = 74880, + SSC_BR_115200 = 115200, + SSC_BR_230400 = 230400, + SSC_BR_460800 = 460800, + SSC_BR_921600 = 921600 +} SscBaudRate; + +/** \defgroup SSC_APIs SSC APIs + * @brief SSC APIs + * + * SSC means simple serial command. + * SSC APIs allows users to define their own command, users can refer to spiffs_test/test_main.c. + * + */ + +/** @addtogroup SSC_APIs + * @{ + */ + +/** + * @brief Initial the ssc function. + * + * @param SscBaudRate bandrate : baud rate + * + * @return null + */ +void ssc_attach(SscBaudRate bandrate); + +/** + * @brief Get the length of the simple serial command. + * + * @param null + * + * @return length of the command. + */ +int ssc_param_len(void); + +/** + * @brief Get the simple serial command string. + * + * @param null + * + * @return the command. + */ +char *ssc_param_str(void); + +/** + * @brief Parse the simple serial command (ssc). + * + * @param char *pLine : [input] the ssc string + * @param char *argv[] : [output] parameters of the ssc + * + * @return the number of parameters. + */ +int ssc_parse_param(char *pLine, char *argv[]); + +/** + * @brief Register the user-defined simple serial command (ssc) set. + * + * @param ssc_cmd_t *cmdset : the ssc set + * @param uint8 cmdnum : number of commands + * @param void (* help)(void) : callback of user-guide + * + * @return null + */ +void ssc_register(ssc_cmd_t *cmdset, uint8 cmdnum, void (* help)(void)); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_SSC_H__ */ diff --git a/include/espressif/esp_sta.h b/include/espressif/esp_sta.h index c0751703..954d3b36 100644 --- a/include/espressif/esp_sta.h +++ b/include/espressif/esp_sta.h @@ -1,393 +1,393 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __ESP_STA_H__ -#define __ESP_STA_H__ - -#include "queue.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup WiFi_APIs WiFi Related APIs - * @brief WiFi APIs - */ - -/** @addtogroup WiFi_APIs - * @{ - */ - -/** \defgroup Station_APIs Station APIs - * @brief ESP8266 station APIs - * @attention To call APIs related to ESP8266 station has to enable station mode - * first (wifi_set_opmode) - */ - -/** @addtogroup Station_APIs - * @{ - */ - -struct station_config { - uint8 ssid[32]; /**< SSID of target AP*/ - uint8 password[64]; /**< password of target AP*/ - uint8 bssid_set; /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/ - uint8 bssid[6]; /**< MAC address of target AP*/ -}; - -/** - * @brief Get the current configuration of the ESP8266 WiFi station. - * - * @param struct station_config *config : ESP8266 station configuration - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_get_config(struct station_config *config); - -/** - * @brief Get the configuration parameters saved in the Flash of the ESP8266 WiFi station. - * - * @param struct station_config *config : ESP8266 station configuration - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_get_config_default(struct station_config *config); - -/** - * @brief Set the configuration of the ESP8266 station and save it to the Flash. - * - * @attention 1. This API can be called only when the ESP8266 station is enabled. - * @attention 2. If wifi_station_set_config is called in user_init , there is no - * need to call wifi_station_connect. - * The ESP8266 station will automatically connect to the AP (router) - * after the system initialization. Otherwise, wifi_station_connect should be called. - * @attention 3. Generally, station_config.bssid_set needs to be 0; and it needs - * to be 1 only when users need to check the MAC address of the AP. - * @attention 4. This configuration will be saved in the Flash system parameter area if changed. - * - * @param struct station_config *config : ESP8266 station configuration - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_set_config(struct station_config *config); - -/** - * @brief Set the configuration of the ESP8266 station. And the configuration - * will not be saved to the Flash. - * - * @attention 1. This API can be called only when the ESP8266 station is enabled. - * @attention 2. If wifi_station_set_config_current is called in user_init , there - * is no need to call wifi_station_connect. - * The ESP8266 station will automatically connect to the AP (router) - * after the system initialization. Otherwise, wifi_station_connect - * should be called. - * @attention 3. Generally, station_config.bssid_set needs to be 0; and it needs - * to be 1 only when users need to check the MAC address of the AP. - * - * @param struct station_config *config : ESP8266 station configuration - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_set_config_current(struct station_config *config); - -/** - * @brief Connect the ESP8266 WiFi station to the AP. - * - * @attention 1. This API should be called when the ESP8266 station is enabled, - * and the system initialization is completed. Do not call this API in user_init. - * @attention 2. If the ESP8266 is connected to an AP, call wifi_station_disconnect to disconnect. - * - * @param null - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_connect(void); - -/** - * @brief Disconnect the ESP8266 WiFi station from the AP. - * - * @attention This API should be called when the ESP8266 station is enabled, - * and the system initialization is completed. Do not call this API in user_init. - * - * @param null - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_disconnect(void); - -struct scan_config { - uint8 *ssid; /**< SSID of AP */ - uint8 *bssid; /**< MAC address of AP */ - uint8 channel; /**< channel, scan the specific channel */ - uint8 show_hidden; /**< enable to scan AP whose SSID is hidden */ -}; - -struct bss_info { - STAILQ_ENTRY(bss_info) next; /**< information of next AP */ - - uint8 bssid[6]; /**< MAC address of AP */ - uint8 ssid[32]; /**< SSID of AP */ - uint8 ssid_len; /**< SSID length */ - uint8 channel; /**< channel of AP */ - sint8 rssi; /**< single strength of AP */ - AUTH_MODE authmode; /**< authmode of AP */ - uint8 is_hidden; /**< SSID of current AP is hidden or not. */ - sint16 freq_offset; /**< frequency offset */ - sint16 freqcal_val; - uint8 *esp_mesh_ie; -}; - -/** - * @brief Callback function for wifi_station_scan. - * - * @param void *arg : information of APs that are found; save them as linked list; - * refer to struct bss_info - * @param STATUS status : status of scanning - * - * @return null - */ -typedef void (* scan_done_cb_t)(void *arg, STATUS status); - -/** - * @brief Scan all available APs. - * - * @attention This API should be called when the ESP8266 station is enabled, and - * the system initialization is completed. Do not call this API in user_init. - * - * @param struct scan_config *config : configuration of scanning - * @param struct scan_done_cb_t cb : callback of scanning - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_scan(struct scan_config *config, scan_done_cb_t cb); - -/** - * @brief Check if the ESP8266 station will connect to the recorded AP automatically - * when the power is on. - * - * @param null - * - * @return true : connect to the AP automatically - * @return false : not connect to the AP automatically - */ -bool wifi_station_get_auto_connect(void); - -/** - * @brief Set whether the ESP8266 station will connect to the recorded AP - * automatically when the power is on. It will do so by default. - * - * @attention 1. If this API is called in user_init, it is effective immediately - * after the power is on. If it is called in other places, it will - * be effective the next time when the power is on. - * @attention 2. This configuration will be saved in Flash system parameter area if changed. - * - * @param bool set : If it will automatically connect to the AP when the power is on - * - true : it will connect automatically - * - false: it will not connect automatically - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_set_auto_connect(bool set); - -/** - * @brief Check whether the ESP8266 station will reconnect to the AP after disconnection. - * - * @param null - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_get_reconnect_policy(void); - -/** - * @brief Set whether the ESP8266 station will reconnect to the AP after disconnection. - * It will do so by default. - * - * @attention If users want to call this API, it is suggested that users call this API in user_init. - * - * @param bool set : if it's true, it will enable reconnection; if it's false, - * it will disable reconnection. - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_set_reconnect_policy(bool set); - -typedef enum { - STATION_IDLE = 0, /**< ESP8266 station idle */ - STATION_CONNECTING, /**< ESP8266 station is connecting to AP*/ - STATION_WRONG_PASSWORD, /**< the password is wrong*/ - STATION_NO_AP_FOUND, /**< ESP8266 station can not find the target AP*/ - STATION_CONNECT_FAIL, /**< ESP8266 station fail to connect to AP*/ - STATION_GOT_IP /**< ESP8266 station got IP address from AP*/ -} STATION_STATUS; - -/** - * @brief Get the connection status of the ESP8266 WiFi station. - * - * @param null - * - * @return the status of connection - */ -STATION_STATUS wifi_station_get_connect_status(void); - -/** - * @brief Get the information of APs (5 at most) recorded by ESP8266 station. - * - * @param struct station_config config[] : information of the APs, the array size should be 5. - * - * @return The number of APs recorded. - */ -uint8 wifi_station_get_current_ap_id(void); - -/** - * @brief Switch the ESP8266 station connection to a recorded AP. - * - * @param uint8 new_ap_id : AP's record id, start counting from 0. - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_ap_change(uint8 current_ap_id); - -/** - * @brief Set the number of APs that can be recorded in the ESP8266 station. - * When the ESP8266 station is connected to an AP, the SSID and password - * of the AP will be recorded. - * - * @attention This configuration will be saved in the Flash system parameter area if changed. - * - * @param uint8 ap_number : the number of APs that can be recorded (MAX: 5) - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_ap_number_set(uint8 ap_number); - -/** - * @brief Get the information of APs (5 at most) recorded by ESP8266 station. - * - * Example: - *
 
-  *         struct station_config config[5];
-  *         nt i = wifi_station_get_ap_info(config);
-  * 
- * - * @param struct station_config config[] : information of the APs, the array size should be 5. - * - * @return The number of APs recorded. - */ -uint8 wifi_station_get_ap_info(struct station_config config[]); - -/** - * @brief Get rssi of the AP which ESP8266 station connected to. - * - * @param null - * - * @return 31 : fail, invalid value. - * @return others : succeed, value of rssi. In general, rssi value < 10 - */ -sint8 wifi_station_get_rssi(void); - -/** - * @brief Enable the ESP8266 station DHCP client. - * - * @attention 1. The DHCP is enabled by default. - * @attention 2. The DHCP and the static IP API ((wifi_set_ip_info)) influence each other, - * and if the DHCP is enabled, the static IP will be disabled; - * if the static IP is enabled, the DHCP will be disabled. - * It depends on the latest configuration. - * - * @param null - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_dhcpc_start(void); - -/** - * @brief Disable the ESP8266 station DHCP client. - * - * @attention 1. The DHCP is enabled by default. - * @attention 2. The DHCP and the static IP API ((wifi_set_ip_info)) influence each other, - * and if the DHCP is enabled, the static IP will be disabled; - * if the static IP is enabled, the DHCP will be disabled. - * It depends on the latest configuration. - * - * @param null - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_dhcpc_stop(void); - -/** - * @brief Get the ESP8266 station DHCP client status. - * - * @param null - * - * @return enum dhcp_status - */ -enum dhcp_status wifi_station_dhcpc_status(void); - -/** - * @brief Set ESP8266 station DHCP hostname. - * - * @param char *name : hostname of ESP8266 station - * - * @return true : succeed - * @return false : fail - */ -bool wifi_station_set_hostname(char *name); - -/** - * @brief Get ESP8266 station DHCP hostname. - * - * @param null - * - * @return the hostname of ESP8266 station - */ -char* wifi_station_get_hostname(void); - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __ESP_STA_H__ +#define __ESP_STA_H__ + +#include "queue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup Station_APIs Station APIs + * @brief ESP8266 station APIs + * @attention To call APIs related to ESP8266 station has to enable station mode + * first (wifi_set_opmode) + */ + +/** @addtogroup Station_APIs + * @{ + */ + +struct station_config { + uint8 ssid[32]; /**< SSID of target AP*/ + uint8 password[64]; /**< password of target AP*/ + uint8 bssid_set; /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/ + uint8 bssid[6]; /**< MAC address of target AP*/ +}; + +/** + * @brief Get the current configuration of the ESP8266 WiFi station. + * + * @param struct station_config *config : ESP8266 station configuration + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_get_config(struct station_config *config); + +/** + * @brief Get the configuration parameters saved in the Flash of the ESP8266 WiFi station. + * + * @param struct station_config *config : ESP8266 station configuration + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_get_config_default(struct station_config *config); + +/** + * @brief Set the configuration of the ESP8266 station and save it to the Flash. + * + * @attention 1. This API can be called only when the ESP8266 station is enabled. + * @attention 2. If wifi_station_set_config is called in user_init , there is no + * need to call wifi_station_connect. + * The ESP8266 station will automatically connect to the AP (router) + * after the system initialization. Otherwise, wifi_station_connect should be called. + * @attention 3. Generally, station_config.bssid_set needs to be 0; and it needs + * to be 1 only when users need to check the MAC address of the AP. + * @attention 4. This configuration will be saved in the Flash system parameter area if changed. + * + * @param struct station_config *config : ESP8266 station configuration + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_set_config(struct station_config *config); + +/** + * @brief Set the configuration of the ESP8266 station. And the configuration + * will not be saved to the Flash. + * + * @attention 1. This API can be called only when the ESP8266 station is enabled. + * @attention 2. If wifi_station_set_config_current is called in user_init , there + * is no need to call wifi_station_connect. + * The ESP8266 station will automatically connect to the AP (router) + * after the system initialization. Otherwise, wifi_station_connect + * should be called. + * @attention 3. Generally, station_config.bssid_set needs to be 0; and it needs + * to be 1 only when users need to check the MAC address of the AP. + * + * @param struct station_config *config : ESP8266 station configuration + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_set_config_current(struct station_config *config); + +/** + * @brief Connect the ESP8266 WiFi station to the AP. + * + * @attention 1. This API should be called when the ESP8266 station is enabled, + * and the system initialization is completed. Do not call this API in user_init. + * @attention 2. If the ESP8266 is connected to an AP, call wifi_station_disconnect to disconnect. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_connect(void); + +/** + * @brief Disconnect the ESP8266 WiFi station from the AP. + * + * @attention This API should be called when the ESP8266 station is enabled, + * and the system initialization is completed. Do not call this API in user_init. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_disconnect(void); + +struct scan_config { + uint8 *ssid; /**< SSID of AP */ + uint8 *bssid; /**< MAC address of AP */ + uint8 channel; /**< channel, scan the specific channel */ + uint8 show_hidden; /**< enable to scan AP whose SSID is hidden */ +}; + +struct bss_info { + STAILQ_ENTRY(bss_info) next; /**< information of next AP */ + + uint8 bssid[6]; /**< MAC address of AP */ + uint8 ssid[32]; /**< SSID of AP */ + uint8 ssid_len; /**< SSID length */ + uint8 channel; /**< channel of AP */ + sint8 rssi; /**< single strength of AP */ + AUTH_MODE authmode; /**< authmode of AP */ + uint8 is_hidden; /**< SSID of current AP is hidden or not. */ + sint16 freq_offset; /**< frequency offset */ + sint16 freqcal_val; + uint8 *esp_mesh_ie; +}; + +/** + * @brief Callback function for wifi_station_scan. + * + * @param void *arg : information of APs that are found; save them as linked list; + * refer to struct bss_info + * @param STATUS status : status of scanning + * + * @return null + */ +typedef void (* scan_done_cb_t)(void *arg, STATUS status); + +/** + * @brief Scan all available APs. + * + * @attention This API should be called when the ESP8266 station is enabled, and + * the system initialization is completed. Do not call this API in user_init. + * + * @param struct scan_config *config : configuration of scanning + * @param struct scan_done_cb_t cb : callback of scanning + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_scan(struct scan_config *config, scan_done_cb_t cb); + +/** + * @brief Check if the ESP8266 station will connect to the recorded AP automatically + * when the power is on. + * + * @param null + * + * @return true : connect to the AP automatically + * @return false : not connect to the AP automatically + */ +bool wifi_station_get_auto_connect(void); + +/** + * @brief Set whether the ESP8266 station will connect to the recorded AP + * automatically when the power is on. It will do so by default. + * + * @attention 1. If this API is called in user_init, it is effective immediately + * after the power is on. If it is called in other places, it will + * be effective the next time when the power is on. + * @attention 2. This configuration will be saved in Flash system parameter area if changed. + * + * @param bool set : If it will automatically connect to the AP when the power is on + * - true : it will connect automatically + * - false: it will not connect automatically + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_set_auto_connect(bool set); + +/** + * @brief Check whether the ESP8266 station will reconnect to the AP after disconnection. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_get_reconnect_policy(void); + +/** + * @brief Set whether the ESP8266 station will reconnect to the AP after disconnection. + * It will do so by default. + * + * @attention If users want to call this API, it is suggested that users call this API in user_init. + * + * @param bool set : if it's true, it will enable reconnection; if it's false, + * it will disable reconnection. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_set_reconnect_policy(bool set); + +typedef enum { + STATION_IDLE = 0, /**< ESP8266 station idle */ + STATION_CONNECTING, /**< ESP8266 station is connecting to AP*/ + STATION_WRONG_PASSWORD, /**< the password is wrong*/ + STATION_NO_AP_FOUND, /**< ESP8266 station can not find the target AP*/ + STATION_CONNECT_FAIL, /**< ESP8266 station fail to connect to AP*/ + STATION_GOT_IP /**< ESP8266 station got IP address from AP*/ +} STATION_STATUS; + +/** + * @brief Get the connection status of the ESP8266 WiFi station. + * + * @param null + * + * @return the status of connection + */ +STATION_STATUS wifi_station_get_connect_status(void); + +/** + * @brief Get the information of APs (5 at most) recorded by ESP8266 station. + * + * @param struct station_config config[] : information of the APs, the array size should be 5. + * + * @return The number of APs recorded. + */ +uint8 wifi_station_get_current_ap_id(void); + +/** + * @brief Switch the ESP8266 station connection to a recorded AP. + * + * @param uint8 new_ap_id : AP's record id, start counting from 0. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_ap_change(uint8 current_ap_id); + +/** + * @brief Set the number of APs that can be recorded in the ESP8266 station. + * When the ESP8266 station is connected to an AP, the SSID and password + * of the AP will be recorded. + * + * @attention This configuration will be saved in the Flash system parameter area if changed. + * + * @param uint8 ap_number : the number of APs that can be recorded (MAX: 5) + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_ap_number_set(uint8 ap_number); + +/** + * @brief Get the information of APs (5 at most) recorded by ESP8266 station. + * + * Example: + *
 
+  *         struct station_config config[5];
+  *         nt i = wifi_station_get_ap_info(config);
+  * 
+ * + * @param struct station_config config[] : information of the APs, the array size should be 5. + * + * @return The number of APs recorded. + */ +uint8 wifi_station_get_ap_info(struct station_config config[]); + +/** + * @brief Get rssi of the AP which ESP8266 station connected to. + * + * @param null + * + * @return 31 : fail, invalid value. + * @return others : succeed, value of rssi. In general, rssi value < 10 + */ +sint8 wifi_station_get_rssi(void); + +/** + * @brief Enable the ESP8266 station DHCP client. + * + * @attention 1. The DHCP is enabled by default. + * @attention 2. The DHCP and the static IP API ((wifi_set_ip_info)) influence each other, + * and if the DHCP is enabled, the static IP will be disabled; + * if the static IP is enabled, the DHCP will be disabled. + * It depends on the latest configuration. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_dhcpc_start(void); + +/** + * @brief Disable the ESP8266 station DHCP client. + * + * @attention 1. The DHCP is enabled by default. + * @attention 2. The DHCP and the static IP API ((wifi_set_ip_info)) influence each other, + * and if the DHCP is enabled, the static IP will be disabled; + * if the static IP is enabled, the DHCP will be disabled. + * It depends on the latest configuration. + * + * @param null + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_dhcpc_stop(void); + +/** + * @brief Get the ESP8266 station DHCP client status. + * + * @param null + * + * @return enum dhcp_status + */ +enum dhcp_status wifi_station_dhcpc_status(void); + +/** + * @brief Set ESP8266 station DHCP hostname. + * + * @param char *name : hostname of ESP8266 station + * + * @return true : succeed + * @return false : fail + */ +bool wifi_station_set_hostname(char *name); + +/** + * @brief Get ESP8266 station DHCP hostname. + * + * @param null + * + * @return the hostname of ESP8266 station + */ +char* wifi_station_get_hostname(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/espressif/esp_system.h b/include/espressif/esp_system.h index 2055e85a..453f0b35 100644 --- a/include/espressif/esp_system.h +++ b/include/espressif/esp_system.h @@ -1,586 +1,586 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __ESP_SYSTEM_H__ -#define __ESP_SYSTEM_H__ - -#include "c_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup System_APIs System APIs - * @brief System APIs - */ - -/** @addtogroup System_APIs - * @{ - */ - -typedef enum { - REASON_DEFAULT_RST = 0, /**< normal startup by power on */ - REASON_WDT_RST, /**< hardware watch dog reset */ - REASON_EXCEPTION_RST, /**< exception reset, GPIO status won't change */ - REASON_SOFT_WDT_RST, /**< software watch dog reset, GPIO status won't change */ - REASON_SOFT_RESTART, /**< software restart ,system_restart , GPIO status won't change */ - REASON_DEEP_SLEEP_AWAKE, /**< wake up from deep-sleep */ - REASON_EXT_SYS_RST /**< external system reset */ -} rst_reason; - -struct rst_info { - rst_reason reason; /**< enum rst_reason */ - uint32 exccause; - uint32 epc1; - uint32 epc2; - uint32 epc3; - uint32 excvaddr; - uint32 depc; - uint32 rtn_addr; -}; - -/** - * @brief Get the reason of restart. - * - * @param null - * - * @return struct rst_info* : information of the system restart - */ -struct rst_info *system_get_rst_info(void); - -/** - * @brief Get information of the SDK version. - * - * @param null - * - * @return Information of the SDK version. - */ -const char *system_get_sdk_version(void); - -/** - * @brief Reset to default settings. - * - * Reset to default settings of the following APIs : wifi_station_set_auto_connect, - * wifi_set_phy_mode, wifi_softap_set_config related, wifi_station_set_config - * related, and wifi_set_opmode. - * - * @param null - * - * @return null - */ -void system_restore(void); - -/** - * @brief Restart system. - * - * @param null - * - * @return null - */ -void system_restart(void); - -/** - * @brief Set the chip to deep-sleep mode. - * - * The device will automatically wake up after the deep-sleep time set - * by the users. Upon waking up, the device boots up from user_init. - * - * @attention 1. XPD_DCDC should be connected to EXT_RSTB through 0 ohm resistor - * in order to support deep-sleep wakeup. - * @attention 2. system_deep_sleep(0): there is no wake up timer; in order to wake - * up, connect a GPIO to pin RST, the chip will wake up by a falling-edge - * on pin RST - * - * @param uint32 time_in_us : deep-sleep time, unit: microsecond - * - * @return null - */ -void system_deep_sleep(uint32 time_in_us); - -/** - * @brief Call this API before system_deep_sleep to set the activity after the - * next deep-sleep wakeup. - * - * If this API is not called, default to be system_deep_sleep_set_option(1). - * - * @param uint8 option : - * @param 0 : Radio calibration after the deep-sleep wakeup is decided by byte - * 108 of esp_init_data_default.bin (0~127byte). - * @param 1 : Radio calibration will be done after the deep-sleep wakeup. This - * will lead to stronger current. - * @param 2 : Radio calibration will not be done after the deep-sleep wakeup. - * This will lead to weaker current. - * @param 4 : Disable radio calibration after the deep-sleep wakeup (the same - * as modem-sleep). This will lead to the weakest current, but the device - * can't receive or transmit data after waking up. - * - * @return true : succeed - * @return false : fail - */ -bool system_deep_sleep_set_option(uint8 option); - -/** - * @brief Get system time, unit: microsecond. - * - * @param null - * - * @return System time, unit: microsecond. - */ -uint32 system_get_time(void); - -/** - * @brief Print the system memory distribution, including data/rodata/bss/heap. - * - * @param null - * - * @return null - */ -void system_print_meminfo(void); - -/** - * @brief Get the size of available heap. - * - * @param null - * - * @return Available heap size. - */ -uint32 system_get_free_heap_size(void); - -/** - * @brief Get the chip ID. - * - * @param null - * - * @return The chip ID. - */ -uint32 system_get_chip_id(void); - -/** - * @brief Get the RTC clock cycle. - * - * @attention 1. The RTC clock cycle has decimal part. - * @attention 2. The RTC clock cycle will change according to the temperature, - * so RTC timer is not very precise. - * - * @param null - * - * @return RTC clock period (unit: microsecond), bit11~ bit0 are decimal. - */ -uint32 system_rtc_clock_cali_proc(void); - -/** - * @brief Get RTC time, unit: RTC clock cycle. - * - * Example: - * If system_get_rtc_time returns 10 (it means 10 RTC cycles), and - * system_rtc_clock_cali_proc returns 5.75 (it means 5.75 microseconds per RTC clock cycle), - * (then the actual time is 10 x 5.75 = 57.5 microseconds. - * - * @attention System time will return to zero because of system_restart, but the - * RTC time still goes on. If the chip is reset by pin EXT_RST or pin - * CHIP_EN (including the deep-sleep wakeup), situations are shown as below: - * @attention 1. reset by pin EXT_RST : RTC memory won't change, RTC timer returns to zero - * @attention 2. watchdog reset : RTC memory won't change, RTC timer won't change - * @attention 3. system_restart : RTC memory won't change, RTC timer won't change - * @attention 4. power on : RTC memory is random value, RTC timer starts from zero - * @attention 5. reset by pin CHIP_EN : RTC memory is random value, RTC timer starts from zero - * - * @param null - * - * @return RTC time. - */ -uint32 system_get_rtc_time(void); - -/** - * @brief Read user data from the RTC memory. - * - * The user data segment (512 bytes, as shown below) is used to store user data. - * - * |<---- system data(256 bytes) ---->|<----------- user data(512 bytes) --------->| - * - * @attention Read and write unit for data stored in the RTC memory is 4 bytes. - * @attention src_addr is the block number (4 bytes per block). So when reading data - * at the beginning of the user data segment, src_addr will be 256/4 = 64, - * n will be data length. - * - * @param uint8 src : source address of rtc memory, src_addr >= 64 - * @param void *dst : data pointer - * @param uint16 n : data length, unit: byte - * - * @return true : succeed - * @return false : fail - */ -bool system_rtc_mem_read(uint8 src, void *dst, uint16 n); - -/** - * @brief Write user data to the RTC memory. - * - * During deep-sleep, only RTC is working. So users can store their data - * in RTC memory if it is needed. The user data segment below (512 bytes) - * is used to store the user data. - * - * |<---- system data(256 bytes) ---->|<----------- user data(512 bytes) --------->| - * - * @attention Read and write unit for data stored in the RTC memory is 4 bytes. - * @attention src_addr is the block number (4 bytes per block). So when storing data - * at the beginning of the user data segment, src_addr will be 256/4 = 64, - * n will be data length. - * - * @param uint8 src : source address of rtc memory, src_addr >= 64 - * @param void *dst : data pointer - * @param uint16 n : data length, unit: byte - * - * @return true : succeed - * @return false : fail - */ -bool system_rtc_mem_write(uint8 dst, const void *src, uint16 n); - -/** - * @brief UART0 swap. - * - * Use MTCK as UART0 RX, MTDO as UART0 TX, so ROM log will not output from - * this new UART0. We also need to use MTDO (U0RTS) and MTCK (U0CTS) as UART0 in hardware. - * - * @param null - * - * @return null - */ -void system_uart_swap(void); - -/** - * @brief Disable UART0 swap. - * - * Use the original UART0, not MTCK and MTDO. - * - * @param null - * - * @return null - */ -void system_uart_de_swap(void); - -/** - * @brief Measure the input voltage of TOUT pin 6, unit : 1/1024 V. - * - * @attention 1. system_adc_read can only be called when the TOUT pin is connected - * to the external circuitry, and the TOUT pin input voltage should - * be limited to 0~1.0V. - * @attention 2. When the TOUT pin is connected to the external circuitry, the 107th - * byte (vdd33_const) of esp_init_data_default.bin(0~127byte) should be - * set as the real power voltage of VDD3P3 pin 3 and 4. - * @attention 3. The unit of vdd33_const is 0.1V, the effective value range is [18, 36]; - * if vdd33_const is in [0, 18) or (36, 255), 3.3V is used to optimize RF by default. - * - * @param null - * - * @return Input voltage of TOUT pin 6, unit : 1/1024 V - */ -uint16 system_adc_read(void); - -/** - * @brief Measure the power voltage of VDD3P3 pin 3 and 4, unit : 1/1024 V. - * - * @attention 1. system_get_vdd33 depends on RF, please do not use it if RF is disabled. - * @attention 2. system_get_vdd33 can only be called when TOUT pin is suspended. - * @attention 3. The 107th byte in esp_init_data_default.bin (0~127byte) is named - * as "vdd33_const", when TOUT pin is suspended vdd33_const must be - * set as 0xFF, that is 255. - * - * @param null - * - * @return Power voltage of VDD33, unit : 1/1024 V - */ -uint16 system_get_vdd33(void); - -/** - * @brief Write data into flash with protection. - * - * Flash read/write has to be 4-bytes aligned. - * - * Protection of flash read/write : - * use 3 sectors (4KBytes per sector) to save 4KB data with protect, - * sector 0 and sector 1 are data sectors, back up each other, - * save data alternately, sector 2 is flag sector, point out which sector - * is keeping the latest data, sector 0 or sector 1. - * - * @param uint16 start_sec : start sector (sector 0) of the 3 sectors which are - * used for flash read/write protection. - * - For example, in IOT_Demo we can use the 3 sectors (3 * 4KB) starting from flash - * 0x3D000 for flash read/write protection, so the parameter start_sec should be 0x3D - * @param void *param : pointer of the data to be written - * @param uint16 len : data length, should be less than a sector, which is 4 * 1024 - * - * @return true : succeed - * @return false : fail - */ -bool system_param_save_with_protect(uint16 start_sec, void *param, uint16 len); - -/** - * @brief Read the data saved into flash with the read/write protection. - * - * Flash read/write has to be 4-bytes aligned. - * - * Read/write protection of flash: - * use 3 sectors (4KB per sector) to save 4KB data with protect, sector - * 0 and sector 1 are data sectors, back up each other, save data alternately, - * sector 2 is flag sector, point out which sector is keeping the latest data, - * sector 0 or sector 1. - * - * @param uint16 start_sec : start sector (sector 0) of the 3 sectors used for - * flash read/write protection. It cannot be sector 1 or sector 2. - * - For example, in IOT_Demo, the 3 sectors (3 * 4KB) starting from flash 0x3D000 - * can be used for flash read/write protection. - * The parameter start_sec is 0x3D, and it cannot be 0x3E or 0x3F. - * @param uint16 offset : offset of data saved in sector - * @param void *param : data pointer - * @param uint16 len : data length, offset + len =< 4 * 1024 - * - * @return true : succeed - * @return false : fail - */ -bool system_param_load(uint16 start_sec, uint16 offset, void *param, uint16 len); - -/** - * @brief Set the maximum value of RF TX Power, unit : 0.25dBm. - * - * @param uint8 max_tpw : the maximum value of RF Tx Power, unit : 0.25dBm, range [0, 82]. - * It can be set refer to the 34th byte (target_power_qdb_0) - * of esp_init_data_default.bin(0~127byte) - * - * @return null - */ -void system_phy_set_max_tpw(uint8 max_tpw); - -/** - * @brief Adjust the RF TX Power according to VDD33, unit : 1/1024 V. - * - * @attention 1. When TOUT pin is suspended, VDD33 can be measured by system_get_vdd33. - * @attention 2. When TOUT pin is connected to the external circuitry, system_get_vdd33 - * can not be used to measure VDD33. - * - * @param uint16 vdd33 : VDD33, unit : 1/1024V, range [1900, 3300] - * - * @return null - */ -void system_phy_set_tpw_via_vdd33(uint16 vdd33); - -/** - * @brief Enable RF or not when wakeup from deep-sleep. - * - * @attention 1. This API can only be called in user_rf_pre_init. - * @attention 2. Function of this API is similar to system_deep_sleep_set_option, - * if they are both called, it will disregard system_deep_sleep_set_option - * which is called before deep-sleep, and refer to system_phy_set_rfoption - * which is called when deep-sleep wake up. - * @attention 3. Before calling this API, system_deep_sleep_set_option should be called - * once at least. - * - * @param uint8 option : - * - 0 : Radio calibration after deep-sleep wake up depends on esp_init_data_default.bin (0~127byte) byte 108. - * - 1 : Radio calibration is done after deep-sleep wake up; this increases the - * current consumption. - * - 2 : No radio calibration after deep-sleep wake up; this reduces the current consumption. - * - 4 : Disable RF after deep-sleep wake up, just like modem sleep; this has the - * least current consumption; the device is not able to transmit or receive - * data after wake up. - * - * @return null - */ -void system_phy_set_rfoption(uint8 option); - -/** @addtogroup Upgrade_APIs - * @{ - */ - -/** - * @brief Check the user bin. - * - * @param null - * - * @return 0x00 : UPGRADE_FW_BIN1, i.e. user1.bin - * @return 0x01 : UPGRADE_FW_BIN2, i.e. user2.bin - */ -uint8 system_upgrade_userbin_check(void); - -/** - * @brief Reboot system to use the new software. - * - * @param null - * - * @return null - */ -void system_upgrade_reboot(void); - -/** - * @brief Check the upgrade status flag. - * - * @param null - * - * @return #define UPGRADE_FLAG_IDLE 0x00 - * @return #define UPGRADE_FLAG_START 0x01 - * @return #define UPGRADE_FLAG_FINISH 0x02 - */ -uint8 system_upgrade_flag_check(); - -/** - * @brief Set the upgrade status flag. - * - * @attention After downloading new softwares, set the flag to UPGRADE_FLAG_FINISH - * and call system_upgrade_reboot to reboot the system in order to run - * the new software. - * - * @param uint8 flag: - * - UPGRADE_FLAG_IDLE 0x00 - * - UPGRADE_FLAG_START 0x01 - * - UPGRADE_FLAG_FINISH 0x02 - * - * @return null - */ -void system_upgrade_flag_set(uint8 flag); - -/** - * @} - */ - -/** \defgroup System_boot_APIs Boot APIs - * @brief boot APIs - */ - -/** @addtogroup System_boot_APIs - * @{ - */ - -#define SYS_BOOT_ENHANCE_MODE 0 /**< It can load and run firmware at any address, for Espressif factory test bin*/ -#define SYS_BOOT_NORMAL_MODE 1 /**< It can only load and run at some addresses of user1.bin (or user2.bin)*/ - -#define SYS_BOOT_NORMAL_BIN 0 /**< user1.bin or user2.bin*/ -#define SYS_BOOT_TEST_BIN 1 /**< can only be Espressif test bin*/ - -/** - * @brief Get information of the boot version. - * - * @attention If boot version >= 1.3 , users can enable the enhanced boot mode - * (refer to system_restart_enhance). - * - * @param null - * - * @return Information of the boot version. - */ -uint8 system_get_boot_version(void); - -/** - * @brief Get the address of the current running user bin (user1.bin or user2.bin). - * - * @param null - * - * @return The address of the current running user bin. - */ -uint32 system_get_userbin_addr(void); - -/** - * @brief Get the boot mode. - * - * @param null - * - * @return #define SYS_BOOT_ENHANCE_MODE 0 - * @return #define SYS_BOOT_NORMAL_MODE 1 - */ -uint8 system_get_boot_mode(void); - -/** - * @brief Restarts the system, and enters the enhanced boot mode. - * - * @attention SYS_BOOT_TEST_BIN is used for factory test during production; users - * can apply for the test bin from Espressif Systems. - * - * @param uint8 bin_type : type of bin - * - #define SYS_BOOT_NORMAL_BIN 0 // user1.bin or user2.bin - * - #define SYS_BOOT_TEST_BIN 1 // can only be Espressif test bin - * @param uint32 bin_addr : starting address of the bin file - * - * @return true : succeed - * @return false : fail - */ -bool system_restart_enhance(uint8 bin_type, uint32 bin_addr); - -typedef enum { - FLASH_SIZE_4M_MAP_256_256 = 0, /**< Flash size : 4Mbits. Map : 256KBytes + 256KBytes */ - FLASH_SIZE_2M, /**< Flash size : 2Mbits. Map : 256KBytes */ - FLASH_SIZE_8M_MAP_512_512, /**< Flash size : 8Mbits. Map : 512KBytes + 512KBytes */ - FLASH_SIZE_16M_MAP_512_512, /**< Flash size : 16Mbits. Map : 512KBytes + 512KBytes */ - FLASH_SIZE_32M_MAP_512_512, /**< Flash size : 32Mbits. Map : 512KBytes + 512KBytes */ - FLASH_SIZE_16M_MAP_1024_1024, /**< Flash size : 16Mbits. Map : 1024KBytes + 1024KBytes */ - FLASH_SIZE_32M_MAP_1024_1024 /**< Flash size : 32Mbits. Map : 1024KBytes + 1024KBytes */ -} flash_size_map; - -/** - * @brief Get the current Flash size and Flash map. - * - * Flash map depends on the selection when compiling, more details in document - * "2A-ESP8266__IOT_SDK_User_Manual" - * - * @param null - * - * @return enum flash_size_map - */ -flash_size_map system_get_flash_size_map(void); - -#define SYS_CPU_80MHZ 80 -#define SYS_CPU_160MHZ 160 - -/** - * @brief Set CPU frequency. Default is 80MHz. - * - * System bus frequency is 80MHz, will not be affected by CPU frequency. - * The frequency of UART, SPI, or other peripheral devices, are divided - * from system bus frequency, so they will not be affected by CPU frequency either. - * - * @param uint8 freq : CPU frequency, 80 or 160. - * - * @return true : succeed - * @return false : fail - */ -bool system_update_cpu_freq(uint8 freq); - -/** - * @brief Get CPU frequency. - * - * @param null - * - * @return CPU frequency, unit : MHz. - */ -uint8 system_get_cpu_freq(void); - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __ESP_SYSTEM_H__ +#define __ESP_SYSTEM_H__ + +#include "c_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup System_APIs System APIs + * @brief System APIs + */ + +/** @addtogroup System_APIs + * @{ + */ + +typedef enum { + REASON_DEFAULT_RST = 0, /**< normal startup by power on */ + REASON_WDT_RST, /**< hardware watch dog reset */ + REASON_EXCEPTION_RST, /**< exception reset, GPIO status won't change */ + REASON_SOFT_WDT_RST, /**< software watch dog reset, GPIO status won't change */ + REASON_SOFT_RESTART, /**< software restart ,system_restart , GPIO status won't change */ + REASON_DEEP_SLEEP_AWAKE, /**< wake up from deep-sleep */ + REASON_EXT_SYS_RST /**< external system reset */ +} rst_reason; + +struct rst_info { + rst_reason reason; /**< enum rst_reason */ + uint32 exccause; + uint32 epc1; + uint32 epc2; + uint32 epc3; + uint32 excvaddr; + uint32 depc; + uint32 rtn_addr; +}; + +/** + * @brief Get the reason of restart. + * + * @param null + * + * @return struct rst_info* : information of the system restart + */ +struct rst_info *system_get_rst_info(void); + +/** + * @brief Get information of the SDK version. + * + * @param null + * + * @return Information of the SDK version. + */ +const char *system_get_sdk_version(void); + +/** + * @brief Reset to default settings. + * + * Reset to default settings of the following APIs : wifi_station_set_auto_connect, + * wifi_set_phy_mode, wifi_softap_set_config related, wifi_station_set_config + * related, and wifi_set_opmode. + * + * @param null + * + * @return null + */ +void system_restore(void); + +/** + * @brief Restart system. + * + * @param null + * + * @return null + */ +void system_restart(void); + +/** + * @brief Set the chip to deep-sleep mode. + * + * The device will automatically wake up after the deep-sleep time set + * by the users. Upon waking up, the device boots up from user_init. + * + * @attention 1. XPD_DCDC should be connected to EXT_RSTB through 0 ohm resistor + * in order to support deep-sleep wakeup. + * @attention 2. system_deep_sleep(0): there is no wake up timer; in order to wake + * up, connect a GPIO to pin RST, the chip will wake up by a falling-edge + * on pin RST + * + * @param uint32 time_in_us : deep-sleep time, unit: microsecond + * + * @return null + */ +void system_deep_sleep(uint32 time_in_us); + +/** + * @brief Call this API before system_deep_sleep to set the activity after the + * next deep-sleep wakeup. + * + * If this API is not called, default to be system_deep_sleep_set_option(1). + * + * @param uint8 option : + * @param 0 : Radio calibration after the deep-sleep wakeup is decided by byte + * 108 of esp_init_data_default.bin (0~127byte). + * @param 1 : Radio calibration will be done after the deep-sleep wakeup. This + * will lead to stronger current. + * @param 2 : Radio calibration will not be done after the deep-sleep wakeup. + * This will lead to weaker current. + * @param 4 : Disable radio calibration after the deep-sleep wakeup (the same + * as modem-sleep). This will lead to the weakest current, but the device + * can't receive or transmit data after waking up. + * + * @return true : succeed + * @return false : fail + */ +bool system_deep_sleep_set_option(uint8 option); + +/** + * @brief Get system time, unit: microsecond. + * + * @param null + * + * @return System time, unit: microsecond. + */ +uint32 system_get_time(void); + +/** + * @brief Print the system memory distribution, including data/rodata/bss/heap. + * + * @param null + * + * @return null + */ +void system_print_meminfo(void); + +/** + * @brief Get the size of available heap. + * + * @param null + * + * @return Available heap size. + */ +uint32 system_get_free_heap_size(void); + +/** + * @brief Get the chip ID. + * + * @param null + * + * @return The chip ID. + */ +uint32 system_get_chip_id(void); + +/** + * @brief Get the RTC clock cycle. + * + * @attention 1. The RTC clock cycle has decimal part. + * @attention 2. The RTC clock cycle will change according to the temperature, + * so RTC timer is not very precise. + * + * @param null + * + * @return RTC clock period (unit: microsecond), bit11~ bit0 are decimal. + */ +uint32 system_rtc_clock_cali_proc(void); + +/** + * @brief Get RTC time, unit: RTC clock cycle. + * + * Example: + * If system_get_rtc_time returns 10 (it means 10 RTC cycles), and + * system_rtc_clock_cali_proc returns 5.75 (it means 5.75 microseconds per RTC clock cycle), + * (then the actual time is 10 x 5.75 = 57.5 microseconds. + * + * @attention System time will return to zero because of system_restart, but the + * RTC time still goes on. If the chip is reset by pin EXT_RST or pin + * CHIP_EN (including the deep-sleep wakeup), situations are shown as below: + * @attention 1. reset by pin EXT_RST : RTC memory won't change, RTC timer returns to zero + * @attention 2. watchdog reset : RTC memory won't change, RTC timer won't change + * @attention 3. system_restart : RTC memory won't change, RTC timer won't change + * @attention 4. power on : RTC memory is random value, RTC timer starts from zero + * @attention 5. reset by pin CHIP_EN : RTC memory is random value, RTC timer starts from zero + * + * @param null + * + * @return RTC time. + */ +uint32 system_get_rtc_time(void); + +/** + * @brief Read user data from the RTC memory. + * + * The user data segment (512 bytes, as shown below) is used to store user data. + * + * |<---- system data(256 bytes) ---->|<----------- user data(512 bytes) --------->| + * + * @attention Read and write unit for data stored in the RTC memory is 4 bytes. + * @attention src_addr is the block number (4 bytes per block). So when reading data + * at the beginning of the user data segment, src_addr will be 256/4 = 64, + * n will be data length. + * + * @param uint8 src : source address of rtc memory, src_addr >= 64 + * @param void *dst : data pointer + * @param uint16 n : data length, unit: byte + * + * @return true : succeed + * @return false : fail + */ +bool system_rtc_mem_read(uint8 src, void *dst, uint16 n); + +/** + * @brief Write user data to the RTC memory. + * + * During deep-sleep, only RTC is working. So users can store their data + * in RTC memory if it is needed. The user data segment below (512 bytes) + * is used to store the user data. + * + * |<---- system data(256 bytes) ---->|<----------- user data(512 bytes) --------->| + * + * @attention Read and write unit for data stored in the RTC memory is 4 bytes. + * @attention src_addr is the block number (4 bytes per block). So when storing data + * at the beginning of the user data segment, src_addr will be 256/4 = 64, + * n will be data length. + * + * @param uint8 src : source address of rtc memory, src_addr >= 64 + * @param void *dst : data pointer + * @param uint16 n : data length, unit: byte + * + * @return true : succeed + * @return false : fail + */ +bool system_rtc_mem_write(uint8 dst, const void *src, uint16 n); + +/** + * @brief UART0 swap. + * + * Use MTCK as UART0 RX, MTDO as UART0 TX, so ROM log will not output from + * this new UART0. We also need to use MTDO (U0RTS) and MTCK (U0CTS) as UART0 in hardware. + * + * @param null + * + * @return null + */ +void system_uart_swap(void); + +/** + * @brief Disable UART0 swap. + * + * Use the original UART0, not MTCK and MTDO. + * + * @param null + * + * @return null + */ +void system_uart_de_swap(void); + +/** + * @brief Measure the input voltage of TOUT pin 6, unit : 1/1024 V. + * + * @attention 1. system_adc_read can only be called when the TOUT pin is connected + * to the external circuitry, and the TOUT pin input voltage should + * be limited to 0~1.0V. + * @attention 2. When the TOUT pin is connected to the external circuitry, the 107th + * byte (vdd33_const) of esp_init_data_default.bin(0~127byte) should be + * set as the real power voltage of VDD3P3 pin 3 and 4. + * @attention 3. The unit of vdd33_const is 0.1V, the effective value range is [18, 36]; + * if vdd33_const is in [0, 18) or (36, 255), 3.3V is used to optimize RF by default. + * + * @param null + * + * @return Input voltage of TOUT pin 6, unit : 1/1024 V + */ +uint16 system_adc_read(void); + +/** + * @brief Measure the power voltage of VDD3P3 pin 3 and 4, unit : 1/1024 V. + * + * @attention 1. system_get_vdd33 depends on RF, please do not use it if RF is disabled. + * @attention 2. system_get_vdd33 can only be called when TOUT pin is suspended. + * @attention 3. The 107th byte in esp_init_data_default.bin (0~127byte) is named + * as "vdd33_const", when TOUT pin is suspended vdd33_const must be + * set as 0xFF, that is 255. + * + * @param null + * + * @return Power voltage of VDD33, unit : 1/1024 V + */ +uint16 system_get_vdd33(void); + +/** + * @brief Write data into flash with protection. + * + * Flash read/write has to be 4-bytes aligned. + * + * Protection of flash read/write : + * use 3 sectors (4KBytes per sector) to save 4KB data with protect, + * sector 0 and sector 1 are data sectors, back up each other, + * save data alternately, sector 2 is flag sector, point out which sector + * is keeping the latest data, sector 0 or sector 1. + * + * @param uint16 start_sec : start sector (sector 0) of the 3 sectors which are + * used for flash read/write protection. + * - For example, in IOT_Demo we can use the 3 sectors (3 * 4KB) starting from flash + * 0x3D000 for flash read/write protection, so the parameter start_sec should be 0x3D + * @param void *param : pointer of the data to be written + * @param uint16 len : data length, should be less than a sector, which is 4 * 1024 + * + * @return true : succeed + * @return false : fail + */ +bool system_param_save_with_protect(uint16 start_sec, void *param, uint16 len); + +/** + * @brief Read the data saved into flash with the read/write protection. + * + * Flash read/write has to be 4-bytes aligned. + * + * Read/write protection of flash: + * use 3 sectors (4KB per sector) to save 4KB data with protect, sector + * 0 and sector 1 are data sectors, back up each other, save data alternately, + * sector 2 is flag sector, point out which sector is keeping the latest data, + * sector 0 or sector 1. + * + * @param uint16 start_sec : start sector (sector 0) of the 3 sectors used for + * flash read/write protection. It cannot be sector 1 or sector 2. + * - For example, in IOT_Demo, the 3 sectors (3 * 4KB) starting from flash 0x3D000 + * can be used for flash read/write protection. + * The parameter start_sec is 0x3D, and it cannot be 0x3E or 0x3F. + * @param uint16 offset : offset of data saved in sector + * @param void *param : data pointer + * @param uint16 len : data length, offset + len =< 4 * 1024 + * + * @return true : succeed + * @return false : fail + */ +bool system_param_load(uint16 start_sec, uint16 offset, void *param, uint16 len); + +/** + * @brief Set the maximum value of RF TX Power, unit : 0.25dBm. + * + * @param uint8 max_tpw : the maximum value of RF Tx Power, unit : 0.25dBm, range [0, 82]. + * It can be set refer to the 34th byte (target_power_qdb_0) + * of esp_init_data_default.bin(0~127byte) + * + * @return null + */ +void system_phy_set_max_tpw(uint8 max_tpw); + +/** + * @brief Adjust the RF TX Power according to VDD33, unit : 1/1024 V. + * + * @attention 1. When TOUT pin is suspended, VDD33 can be measured by system_get_vdd33. + * @attention 2. When TOUT pin is connected to the external circuitry, system_get_vdd33 + * can not be used to measure VDD33. + * + * @param uint16 vdd33 : VDD33, unit : 1/1024V, range [1900, 3300] + * + * @return null + */ +void system_phy_set_tpw_via_vdd33(uint16 vdd33); + +/** + * @brief Enable RF or not when wakeup from deep-sleep. + * + * @attention 1. This API can only be called in user_rf_pre_init. + * @attention 2. Function of this API is similar to system_deep_sleep_set_option, + * if they are both called, it will disregard system_deep_sleep_set_option + * which is called before deep-sleep, and refer to system_phy_set_rfoption + * which is called when deep-sleep wake up. + * @attention 3. Before calling this API, system_deep_sleep_set_option should be called + * once at least. + * + * @param uint8 option : + * - 0 : Radio calibration after deep-sleep wake up depends on esp_init_data_default.bin (0~127byte) byte 108. + * - 1 : Radio calibration is done after deep-sleep wake up; this increases the + * current consumption. + * - 2 : No radio calibration after deep-sleep wake up; this reduces the current consumption. + * - 4 : Disable RF after deep-sleep wake up, just like modem sleep; this has the + * least current consumption; the device is not able to transmit or receive + * data after wake up. + * + * @return null + */ +void system_phy_set_rfoption(uint8 option); + +/** @addtogroup Upgrade_APIs + * @{ + */ + +/** + * @brief Check the user bin. + * + * @param null + * + * @return 0x00 : UPGRADE_FW_BIN1, i.e. user1.bin + * @return 0x01 : UPGRADE_FW_BIN2, i.e. user2.bin + */ +uint8 system_upgrade_userbin_check(void); + +/** + * @brief Reboot system to use the new software. + * + * @param null + * + * @return null + */ +void system_upgrade_reboot(void); + +/** + * @brief Check the upgrade status flag. + * + * @param null + * + * @return #define UPGRADE_FLAG_IDLE 0x00 + * @return #define UPGRADE_FLAG_START 0x01 + * @return #define UPGRADE_FLAG_FINISH 0x02 + */ +uint8 system_upgrade_flag_check(); + +/** + * @brief Set the upgrade status flag. + * + * @attention After downloading new softwares, set the flag to UPGRADE_FLAG_FINISH + * and call system_upgrade_reboot to reboot the system in order to run + * the new software. + * + * @param uint8 flag: + * - UPGRADE_FLAG_IDLE 0x00 + * - UPGRADE_FLAG_START 0x01 + * - UPGRADE_FLAG_FINISH 0x02 + * + * @return null + */ +void system_upgrade_flag_set(uint8 flag); + +/** + * @} + */ + +/** \defgroup System_boot_APIs Boot APIs + * @brief boot APIs + */ + +/** @addtogroup System_boot_APIs + * @{ + */ + +#define SYS_BOOT_ENHANCE_MODE 0 /**< It can load and run firmware at any address, for Espressif factory test bin*/ +#define SYS_BOOT_NORMAL_MODE 1 /**< It can only load and run at some addresses of user1.bin (or user2.bin)*/ + +#define SYS_BOOT_NORMAL_BIN 0 /**< user1.bin or user2.bin*/ +#define SYS_BOOT_TEST_BIN 1 /**< can only be Espressif test bin*/ + +/** + * @brief Get information of the boot version. + * + * @attention If boot version >= 1.3 , users can enable the enhanced boot mode + * (refer to system_restart_enhance). + * + * @param null + * + * @return Information of the boot version. + */ +uint8 system_get_boot_version(void); + +/** + * @brief Get the address of the current running user bin (user1.bin or user2.bin). + * + * @param null + * + * @return The address of the current running user bin. + */ +uint32 system_get_userbin_addr(void); + +/** + * @brief Get the boot mode. + * + * @param null + * + * @return #define SYS_BOOT_ENHANCE_MODE 0 + * @return #define SYS_BOOT_NORMAL_MODE 1 + */ +uint8 system_get_boot_mode(void); + +/** + * @brief Restarts the system, and enters the enhanced boot mode. + * + * @attention SYS_BOOT_TEST_BIN is used for factory test during production; users + * can apply for the test bin from Espressif Systems. + * + * @param uint8 bin_type : type of bin + * - #define SYS_BOOT_NORMAL_BIN 0 // user1.bin or user2.bin + * - #define SYS_BOOT_TEST_BIN 1 // can only be Espressif test bin + * @param uint32 bin_addr : starting address of the bin file + * + * @return true : succeed + * @return false : fail + */ +bool system_restart_enhance(uint8 bin_type, uint32 bin_addr); + +typedef enum { + FLASH_SIZE_4M_MAP_256_256 = 0, /**< Flash size : 4Mbits. Map : 256KBytes + 256KBytes */ + FLASH_SIZE_2M, /**< Flash size : 2Mbits. Map : 256KBytes */ + FLASH_SIZE_8M_MAP_512_512, /**< Flash size : 8Mbits. Map : 512KBytes + 512KBytes */ + FLASH_SIZE_16M_MAP_512_512, /**< Flash size : 16Mbits. Map : 512KBytes + 512KBytes */ + FLASH_SIZE_32M_MAP_512_512, /**< Flash size : 32Mbits. Map : 512KBytes + 512KBytes */ + FLASH_SIZE_16M_MAP_1024_1024, /**< Flash size : 16Mbits. Map : 1024KBytes + 1024KBytes */ + FLASH_SIZE_32M_MAP_1024_1024 /**< Flash size : 32Mbits. Map : 1024KBytes + 1024KBytes */ +} flash_size_map; + +/** + * @brief Get the current Flash size and Flash map. + * + * Flash map depends on the selection when compiling, more details in document + * "2A-ESP8266__IOT_SDK_User_Manual" + * + * @param null + * + * @return enum flash_size_map + */ +flash_size_map system_get_flash_size_map(void); + +#define SYS_CPU_80MHZ 80 +#define SYS_CPU_160MHZ 160 + +/** + * @brief Set CPU frequency. Default is 80MHz. + * + * System bus frequency is 80MHz, will not be affected by CPU frequency. + * The frequency of UART, SPI, or other peripheral devices, are divided + * from system bus frequency, so they will not be affected by CPU frequency either. + * + * @param uint8 freq : CPU frequency, 80 or 160. + * + * @return true : succeed + * @return false : fail + */ +bool system_update_cpu_freq(uint8 freq); + +/** + * @brief Get CPU frequency. + * + * @param null + * + * @return CPU frequency, unit : MHz. + */ +uint8 system_get_cpu_freq(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/espressif/esp_timer.h b/include/espressif/esp_timer.h index 6fb6e1fe..854faba9 100644 --- a/include/espressif/esp_timer.h +++ b/include/espressif/esp_timer.h @@ -1,101 +1,101 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __ESP_TIMER_H__ -#define __ESP_TIMER_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* timer related */ -typedef void os_timer_func_t(void *timer_arg); - -typedef struct _os_timer_t { - struct _os_timer_t *timer_next; - void *timer_handle; - uint32 timer_expire; - uint32 timer_period; - os_timer_func_t *timer_func; - bool timer_repeat_flag; - void *timer_arg; -} os_timer_t; - -/** \defgroup Timer_APIs Software timer APIs - * @brief Software timer APIs - * - * Timers of the following interfaces are software timers. Functions of the timers are executed during the tasks. - * Since a task can be stopped, or be delayed because there are other tasks with higher priorities, the following os_timer interfaces cannot guarantee the precise execution of the timers. - * - For the same timer, os_timer_arm (or os_timer_arm_us) cannot be invoked repeatedly. os_timer_disarm should be invoked first. - * - os_timer_setfn can only be invoked when the timer is not enabled, i.e., after os_timer_disarm or before os_timer_arm (or os_timer_arm_us). - * - */ - -/** @addtogroup Timer_APIs - * @{ - */ - -/** - * @brief Set the timer callback function. - * - * @attention 1. The callback function must be set in order to enable the timer. - * @attention 2. Operating system scheduling is disabled in timer callback. - * - * @param os_timer_t *ptimer : Timer structure - * @param os_timer_func_t *pfunction : timer callback function - * @param void *parg : callback function parameter - * - * @return null - */ -void os_timer_setfn(os_timer_t *ptimer, os_timer_func_t *pfunction, void *parg); - -/** - * @brief Enable the millisecond timer. - * - * @param os_timer_t *ptimer : timer structure - * @param uint32_t milliseconds : Timing, unit: millisecond, range: 5 ~ 0x68DB8 - * @param bool repeat_flag : Whether the timer will be invoked repeatedly or not - * - * @return null - */ -void os_timer_arm(os_timer_t *ptimer, uint32 msec, bool repeat_flag); - -/** - * @brief Disarm the timer - * - * @param os_timer_t *ptimer : Timer structure - * - * @return null - */ -void os_timer_disarm(os_timer_t *ptimer); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __ESP_TIMER_H__ +#define __ESP_TIMER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* timer related */ +typedef void os_timer_func_t(void *timer_arg); + +typedef struct _os_timer_t { + struct _os_timer_t *timer_next; + void *timer_handle; + uint32 timer_expire; + uint32 timer_period; + os_timer_func_t *timer_func; + bool timer_repeat_flag; + void *timer_arg; +} os_timer_t; + +/** \defgroup Timer_APIs Software timer APIs + * @brief Software timer APIs + * + * Timers of the following interfaces are software timers. Functions of the timers are executed during the tasks. + * Since a task can be stopped, or be delayed because there are other tasks with higher priorities, the following os_timer interfaces cannot guarantee the precise execution of the timers. + * - For the same timer, os_timer_arm (or os_timer_arm_us) cannot be invoked repeatedly. os_timer_disarm should be invoked first. + * - os_timer_setfn can only be invoked when the timer is not enabled, i.e., after os_timer_disarm or before os_timer_arm (or os_timer_arm_us). + * + */ + +/** @addtogroup Timer_APIs + * @{ + */ + +/** + * @brief Set the timer callback function. + * + * @attention 1. The callback function must be set in order to enable the timer. + * @attention 2. Operating system scheduling is disabled in timer callback. + * + * @param os_timer_t *ptimer : Timer structure + * @param os_timer_func_t *pfunction : timer callback function + * @param void *parg : callback function parameter + * + * @return null + */ +void os_timer_setfn(os_timer_t *ptimer, os_timer_func_t *pfunction, void *parg); + +/** + * @brief Enable the millisecond timer. + * + * @param os_timer_t *ptimer : timer structure + * @param uint32_t milliseconds : Timing, unit: millisecond, range: 5 ~ 0x68DB8 + * @param bool repeat_flag : Whether the timer will be invoked repeatedly or not + * + * @return null + */ +void os_timer_arm(os_timer_t *ptimer, uint32 msec, bool repeat_flag); + +/** + * @brief Disarm the timer + * + * @param os_timer_t *ptimer : Timer structure + * + * @return null + */ +void os_timer_disarm(os_timer_t *ptimer); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/espressif/esp_wifi.h b/include/espressif/esp_wifi.h index 2e48d911..4636c245 100644 --- a/include/espressif/esp_wifi.h +++ b/include/espressif/esp_wifi.h @@ -1,989 +1,989 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __ESP_WIFI_H__ -#define __ESP_WIFI_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup WiFi_APIs WiFi Related APIs - * @brief WiFi APIs - */ - -/** @addtogroup WiFi_APIs - * @{ - */ - -/** \defgroup WiFi_Common_APIs Common APIs - * @brief WiFi common APIs - * - * The Flash system parameter area is the last 16KB of the Flash. - * - */ - -/** @addtogroup WiFi_Common_APIs - * @{ - */ - -typedef enum { - NULL_MODE = 0, /**< null mode */ - STATION_MODE, /**< WiFi station mode */ - SOFTAP_MODE, /**< WiFi soft-AP mode */ - STATIONAP_MODE, /**< WiFi station + soft-AP mode */ - MAX_MODE -} WIFI_MODE; - -typedef enum { - AUTH_OPEN = 0, /**< authenticate mode : open */ - AUTH_WEP, /**< authenticate mode : WEP */ - AUTH_WPA_PSK, /**< authenticate mode : WPA_PSK */ - AUTH_WPA2_PSK, /**< authenticate mode : WPA2_PSK */ - AUTH_WPA_WPA2_PSK, /**< authenticate mode : WPA_WPA2_PSK */ - AUTH_MAX -} AUTH_MODE; - -/** - * @brief Get the current operating mode of the WiFi. - * - * @param null - * - * @return WiFi operating modes: - * - 0x01: station mode; - * - 0x02: soft-AP mode - * - 0x03: station+soft-AP mode - */ -WIFI_MODE wifi_get_opmode(void); - -/** - * @brief Get the operating mode of the WiFi saved in the Flash. - * - * @param null - * - * @return WiFi operating modes: - * - 0x01: station mode; - * - 0x02: soft-AP mode - * - 0x03: station+soft-AP mode - */ -WIFI_MODE wifi_get_opmode_default(void); - -/** - * @brief Set the WiFi operating mode, and save it to Flash. - * - * Set the WiFi operating mode as station, soft-AP or station+soft-AP, - * and save it to Flash. The default mode is soft-AP mode. - * - * @attention This configuration will be saved in the Flash system parameter area if changed. - * - * @param uint8 opmode : WiFi operating modes: - * - 0x01: station mode; - * - 0x02: soft-AP mode - * - 0x03: station+soft-AP mode - * - * @return true : succeed - * @return false : fail - */ -bool wifi_set_opmode(WIFI_MODE opmode); - -/** - * @brief Set the WiFi operating mode, and will not save it to Flash. - * - * Set the WiFi operating mode as station, soft-AP or station+soft-AP, and - * the mode won't be saved to the Flash. - * - * @param uint8 opmode : WiFi operating modes: - * - 0x01: station mode; - * - 0x02: soft-AP mode - * - 0x03: station+soft-AP mode - * - * @return true : succeed - * @return false : fail - */ -bool wifi_set_opmode_current(WIFI_MODE opmode); - -typedef enum { - STATION_IF = 0, /**< ESP8266 station interface */ - SOFTAP_IF, /**< ESP8266 soft-AP interface */ - MAX_IF -} WIFI_INTERFACE; - -struct ip_info { - struct ip_addr ip; /**< IP address */ - struct ip_addr netmask; /**< netmask */ - struct ip_addr gw; /**< gateway */ -}; - -/** - * @brief Get the IP address of the ESP8266 WiFi station or the soft-AP interface. - * - * @attention Users need to enable the target interface (station or soft-AP) by wifi_set_opmode first. - * - * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, - * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. - * @param struct ip_info *info : the IP information obtained. - * - * @return true : succeed - * @return false : fail - */ -bool wifi_get_ip_info(WIFI_INTERFACE if_index, struct ip_info *info); - -/** - * @brief Set the IP address of the ESP8266 WiFi station or the soft-AP interface. - * - * @attention 1. Users need to enable the target interface (station or soft-AP) by - * wifi_set_opmode first. - * @attention 2. To set static IP, users need to disable DHCP first (wifi_station_dhcpc_stop - * or wifi_softap_dhcps_stop): - * - If the DHCP is enabled, the static IP will be disabled; if the static IP is enabled, - * the DHCP will be disabled. It depends on the latest configuration. - * - * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, - * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. - * @param struct ip_info *info : the IP information obtained. - * - * @return true : succeed - * @return false : fail - */ -bool wifi_set_ip_info(WIFI_INTERFACE if_index, struct ip_info *info); - -/** - * @brief Get MAC address of the ESP8266 WiFi station or the soft-AP interface. - * - * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, - * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. - * @param uint8 *macaddr : the MAC address. - * - * @return true : succeed - * @return false : fail - */ -bool wifi_get_macaddr(WIFI_INTERFACE if_index, uint8 *macaddr); - -/** - * @brief Set MAC address of the ESP8266 WiFi station or the soft-AP interface. - * - * @attention 1. This API can only be called in user_init. - * @attention 2. Users need to enable the target interface (station or soft-AP) by wifi_set_opmode first. - * @attention 3. ESP8266 soft-AP and station have different MAC addresses, do not set them to be the same. - * - The bit0 of the first byte of ESP8266 MAC address can not be 1. For example, the MAC address - * can set to be "1a:XX:XX:XX:XX:XX", but can not be "15:XX:XX:XX:XX:XX". - * - * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, - * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. - * @param uint8 *macaddr : the MAC address. - * - * @return true : succeed - * @return false : fail - */ -bool wifi_set_macaddr(WIFI_INTERFACE if_index, uint8 *macaddr); - -/** - * @brief Install the WiFi status LED. - * - * @param uint8 gpio_id : GPIO ID - * @param uint8 gpio_name : GPIO mux name - * @param uint8 gpio_func : GPIO function - * - * @return null - */ -void wifi_status_led_install(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func); - -/** - * @brief Uninstall the WiFi status LED. - * - * @param null - * - * @return null - */ -void wifi_status_led_uninstall(void); - -typedef enum { - PHY_MODE_11B = 1, /**< 802.11b */ - PHY_MODE_11G = 2, /**< 802.11g */ - PHY_MODE_11N = 3 /**< 802.11n */ -} WIFI_PHY_MODE; - -/** - * @brief Get the ESP8266 physical mode (802.11b/g/n). - * - * @param null - * - * @return enum WIFI_PHY_MODE - */ -WIFI_PHY_MODE wifi_get_phy_mode(void); - -/** - * @brief Set the ESP8266 physical mode (802.11b/g/n). - * - * @attention The ESP8266 soft-AP only supports bg. - * - * @param WIFI_PHY_MODE mode : physical mode - * - * @return true : succeed - * @return false : fail - */ -bool wifi_set_phy_mode(WIFI_PHY_MODE mode); - -typedef enum { - EVENT_STAMODE_SCAN_DONE = 0, /**< ESP8266 station finish scanning AP */ - EVENT_STAMODE_CONNECTED, /**< ESP8266 station connected to AP */ - EVENT_STAMODE_DISCONNECTED, /**< ESP8266 station disconnected to AP */ - EVENT_STAMODE_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP8266 station changed */ - EVENT_STAMODE_GOT_IP, /**< ESP8266 station got IP from connected AP */ - EVENT_STAMODE_DHCP_TIMEOUT, /**< ESP8266 station dhcp client got IP timeout */ - EVENT_SOFTAPMODE_STACONNECTED, /**< a station connected to ESP8266 soft-AP */ - EVENT_SOFTAPMODE_STADISCONNECTED, /**< a station disconnected to ESP8266 soft-AP */ - EVENT_SOFTAPMODE_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */ - EVENT_MAX -} SYSTEM_EVENT; - -enum { - REASON_UNSPECIFIED = 1, - REASON_AUTH_EXPIRE = 2, - REASON_AUTH_LEAVE = 3, - REASON_ASSOC_EXPIRE = 4, - REASON_ASSOC_TOOMANY = 5, - REASON_NOT_AUTHED = 6, - REASON_NOT_ASSOCED = 7, - REASON_ASSOC_LEAVE = 8, - REASON_ASSOC_NOT_AUTHED = 9, - REASON_DISASSOC_PWRCAP_BAD = 10, - REASON_DISASSOC_SUPCHAN_BAD = 11, - REASON_IE_INVALID = 13, - REASON_MIC_FAILURE = 14, - REASON_4WAY_HANDSHAKE_TIMEOUT = 15, - REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, - REASON_IE_IN_4WAY_DIFFERS = 17, - REASON_GROUP_CIPHER_INVALID = 18, - REASON_PAIRWISE_CIPHER_INVALID = 19, - REASON_AKMP_INVALID = 20, - REASON_UNSUPP_RSN_IE_VERSION = 21, - REASON_INVALID_RSN_IE_CAP = 22, - REASON_802_1X_AUTH_FAILED = 23, - REASON_CIPHER_SUITE_REJECTED = 24, - - REASON_BEACON_TIMEOUT = 200, - REASON_NO_AP_FOUND = 201, - REASON_AUTH_FAIL = 202, - REASON_ASSOC_FAIL = 203, - REASON_HANDSHAKE_TIMEOUT = 204, -}; - -typedef struct { - uint32 status; /**< status of scanning APs*/ - struct bss_info *bss; /**< list of APs found*/ -} Event_StaMode_ScanDone_t; - -typedef struct { - uint8 ssid[32]; /**< SSID of connected AP */ - uint8 ssid_len; /**< SSID length of connected AP */ - uint8 bssid[6]; /**< BSSID of connected AP*/ - uint8 channel; /**< channel of connected AP*/ -} Event_StaMode_Connected_t; - -typedef struct { - uint8 ssid[32]; /**< SSID of disconnected AP */ - uint8 ssid_len; /**< SSID length of disconnected AP */ - uint8 bssid[6]; /**< BSSID of disconnected AP */ - uint8 reason; /**< reason of disconnection */ -} Event_StaMode_Disconnected_t; - -typedef struct { - uint8 old_mode; /**< the old auth mode of AP */ - uint8 new_mode; /**< the new auth mode of AP */ -} Event_StaMode_AuthMode_Change_t; - -typedef struct { - struct ip_addr ip; /**< IP address that ESP8266 station got from connected AP */ - struct ip_addr mask; /**< netmask that ESP8266 station got from connected AP */ - struct ip_addr gw; /**< gateway that ESP8266 station got from connected AP */ -} Event_StaMode_Got_IP_t; - -typedef struct { - uint8 mac[6]; /**< MAC address of the station connected to ESP8266 soft-AP */ - uint8 aid; /**< the aid that ESP8266 soft-AP gives to the station connected to */ -} Event_SoftAPMode_StaConnected_t; - -typedef struct { - uint8 mac[6]; /**< MAC address of the station disconnects to ESP8266 soft-AP */ - uint8 aid; /**< the aid that ESP8266 soft-AP gave to the station disconnects to */ -} Event_SoftAPMode_StaDisconnected_t; - -typedef struct { - int rssi; /**< Received probe request signal strength */ - uint8 mac[6]; /**< MAC address of the station which send probe request */ -} Event_SoftAPMode_ProbeReqRecved_t; - -typedef union { - Event_StaMode_ScanDone_t scan_done; /**< ESP8266 station scan (APs) done */ - Event_StaMode_Connected_t connected; /**< ESP8266 station connected to AP */ - Event_StaMode_Disconnected_t disconnected; /**< ESP8266 station disconnected to AP */ - Event_StaMode_AuthMode_Change_t auth_change; /**< the auth mode of AP ESP8266 station connected to changed */ - Event_StaMode_Got_IP_t got_ip; /**< ESP8266 station got IP */ - Event_SoftAPMode_StaConnected_t sta_connected; /**< a station connected to ESP8266 soft-AP */ - Event_SoftAPMode_StaDisconnected_t sta_disconnected; /**< a station disconnected to ESP8266 soft-AP */ - Event_SoftAPMode_ProbeReqRecved_t ap_probereqrecved; /**< ESP8266 softAP receive probe request packet */ -} Event_Info_u; - -typedef struct _esp_event { - SYSTEM_EVENT event_id; /**< even ID */ - Event_Info_u event_info; /**< event information */ -} System_Event_t; - -/** - * @brief The Wi-Fi event handler. - * - * @attention No complex operations are allowed in callback. - * If users want to execute any complex operations, please post message to another task instead. - * - * @param System_Event_t *event : WiFi event - * - * @return null - */ -typedef void (* wifi_event_handler_cb_t)(System_Event_t *event); - -/** - * @brief Register the Wi-Fi event handler. - * - * @param wifi_event_handler_cb_t cb : callback function - * - * @return true : succeed - * @return false : fail - */ -bool wifi_set_event_handler_cb(wifi_event_handler_cb_t cb); - -/** - * @brief Callback of sending user-define 802.11 packets. - * - * @param uint8 status : 0, packet sending succeed; otherwise, fail. - * - * @return null - */ -typedef void (*freedom_outside_cb_t)(uint8 status); - -/** - * @brief Register a callback for sending user-define 802.11 packets. - * - * @attention Only after the previous packet was sent, entered the freedom_outside_cb_t, - * the next packet is allowed to send. - * - * @param freedom_outside_cb_t cb : sent callback - * - * @return 0, succeed; - * @return -1, fail. - */ -sint32 wifi_register_send_pkt_freedom_cb(freedom_outside_cb_t cb); - -/** - * @brief Unregister the callback for sending user-define 802.11 packets. - * - * @param null - * - * @return null - */ -void wifi_unregister_send_pkt_freedom_cb(void); - -/** - * @brief Send user-define 802.11 packets. - * - * @attention 1. Packet has to be the whole 802.11 packet, does not include the FCS. - * The length of the packet has to be longer than the minimum length - * of the header of 802.11 packet which is 24 bytes, and less than 1400 bytes. - * @attention 2. Duration area is invalid for user, it will be filled in SDK. - * @attention 3. The rate of sending packet is same as the management packet which - * is the same as the system rate of sending packets. - * @attention 4. Only after the previous packet was sent, entered the sent callback, - * the next packet is allowed to send. Otherwise, wifi_send_pkt_freedom - * will return fail. - * - * @param uint8 *buf : pointer of packet - * @param uint16 len : packet length - * @param bool sys_seq : follow the system's 802.11 packets sequence number or not, - * if it is true, the sequence number will be increased 1 every - * time a packet sent. - * - * @return 0, succeed; - * @return -1, fail. - */ -sint32 wifi_send_pkt_freedom(uint8 *buf, uint16 len, bool sys_seq); - -/** - * @brief Enable RFID LOCP (Location Control Protocol) to receive WDS packets. - * - * @param null - * - * @return 0, succeed; - * @return otherwise, fail. - */ -sint32 wifi_rfid_locp_recv_open(void); - -/** - * @brief Disable RFID LOCP (Location Control Protocol) . - * - * @param null - * - * @return null - */ -void wifi_rfid_locp_recv_close(void); - -/** - * @brief RFID LOCP (Location Control Protocol) receive callback . - * - * @param uint8 *frm : point to the head of 802.11 packet - * @param int len : packet length - * @param int rssi : signal strength - * - * @return null - */ -typedef void (*rfid_locp_cb_t)(uint8 *frm, int len, sint8 rssi); - -/** - * @brief Register a callback of receiving WDS packets. - * - * Register a callback of receiving WDS packets. Only if the first MAC - * address of the WDS packet is a multicast address. - * - * @param rfid_locp_cb_t cb : callback - * - * @return 0, succeed; - * @return otherwise, fail. - */ -sint32 wifi_register_rfid_locp_recv_cb(rfid_locp_cb_t cb); - -/** - * @brief Unregister the callback of receiving WDS packets. - * - * @param null - * - * @return null - */ -void wifi_unregister_rfid_locp_recv_cb(void); - -typedef enum { - NONE_SLEEP_T = 0, - LIGHT_SLEEP_T, - MODEM_SLEEP_T -} sleep_type; - -/** - * @brief Sets sleep type. - * - * Set NONE_SLEEP_T to disable sleep. Default to be Modem sleep. - * - * @attention Sleep function only takes effect in station-only mode. - * - * @param sleep_type type : sleep type - * - * @return true : succeed - * @return false : fail - */ -bool wifi_set_sleep_type(sleep_type type); - -/** - * @brief Gets sleep type. - * - * @param null - * - * @return sleep type - */ -sleep_type wifi_get_sleep_type(void); - -/** - * @} - */ - - -/** \defgroup WiFi_Force_Sleep_APIs Force Sleep APIs - * @brief WiFi Force Sleep APIs - */ - -/** @addtogroup WiFi_Force_Sleep_APIs - * @{ - */ - -/** - * @brief Enable force sleep function. - * - * @attention Force sleep function is disabled by default. - * - * @param null - * - * @return null - */ -void wifi_fpm_open(void); - -/** - * @brief Disable force sleep function. - * - * @param null - * - * @return null - */ -void wifi_fpm_close(void); - -/** - * @brief Wake ESP8266 up from MODEM_SLEEP_T force sleep. - * - * @attention This API can only be called when MODEM_SLEEP_T force sleep function - * is enabled, after calling wifi_fpm_open. - * This API can not be called after calling wifi_fpm_close. - * - * @param null - * - * @return null - */ -void wifi_fpm_do_wakeup(void); - -typedef void (*fpm_wakeup_cb)(void); - -/** - * @brief Set a callback of waken up from force sleep because of time out. - * - * @attention 1. This API can only be called when force sleep function is enabled, - * after calling wifi_fpm_open. This API can not be called after calling - * wifi_fpm_close. - * @attention 2. fpm_wakeup_cb_func will be called after system woke up only if the - * force sleep time out (wifi_fpm_do_sleep and the parameter is not 0xFFFFFFF). - * @attention 3. fpm_wakeup_cb_func will not be called if woke up by wifi_fpm_do_wakeup - * from MODEM_SLEEP_T type force sleep. - * - * @param void (*fpm_wakeup_cb_func)(void) : callback of waken up - * - * @return null - */ -void wifi_fpm_set_wakeup_cb(fpm_wakeup_cb cb); - -/** - * @brief Force ESP8266 enter sleep mode, and it will wake up automatically when time out. - * - * @attention 1. This API can only be called when force sleep function is enabled, after - * calling wifi_fpm_open. This API can not be called after calling wifi_fpm_close. - * @attention 2. If this API returned 0 means that the configuration is set successfully, - * but the ESP8266 will not enter sleep mode immediately, it is going to sleep - * in the system idle task. Please do not call other WiFi related function right - * after calling this API. - * - * @param uint32 sleep_time_in_us : sleep time, ESP8266 will wake up automatically - * when time out. Unit: us. Range: 10000 ~ 268435455(0xFFFFFFF). - * - If sleep_time_in_us is 0xFFFFFFF, the ESP8266 will sleep till - * - if wifi_fpm_set_sleep_type is set to be LIGHT_SLEEP_T, ESP8266 can wake up by GPIO. - * - if wifi_fpm_set_sleep_type is set to be MODEM_SLEEP_T, ESP8266 can wake up by wifi_fpm_do_wakeup. - * - * @return 0, setting succeed; - * @return -1, fail to sleep, sleep status error; - * @return -2, fail to sleep, force sleep function is not enabled. - */ -sint8 wifi_fpm_do_sleep(uint32 sleep_time_in_us); - -/** - * @brief Set sleep type for force sleep function. - * - * @attention This API can only be called before wifi_fpm_open. - * - * @param sleep_type type : sleep type - * - * @return null - */ -void wifi_fpm_set_sleep_type(sleep_type type); - -/** - * @brief Get sleep type of force sleep function. - * - * @param null - * - * @return sleep type - */ -sleep_type wifi_fpm_get_sleep_type(void); - -/** - * @} - */ - -/** \defgroup WiFi_Rate_Control_APIs Rate Control APIs - * @brief WiFi Rate Control APIs - */ - -/** @addtogroup WiFi_Rate_Control_APIs - * @{ - */ - -enum FIXED_RATE { - PHY_RATE_48 = 0x8, - PHY_RATE_24 = 0x9, - PHY_RATE_12 = 0xA, - PHY_RATE_6 = 0xB, - PHY_RATE_54 = 0xC, - PHY_RATE_36 = 0xD, - PHY_RATE_18 = 0xE, - PHY_RATE_9 = 0xF -}; - -#define FIXED_RATE_MASK_NONE 0x00 -#define FIXED_RATE_MASK_STA 0x01 -#define FIXED_RATE_MASK_AP 0x02 -#define FIXED_RATE_MASK_ALL 0x03 - -/** - * @brief Set the fixed rate and mask of sending data from ESP8266. - * - * @attention 1. Only if the corresponding bit in enable_mask is 1, ESP8266 station - * or soft-AP will send data in the fixed rate. - * @attention 2. If the enable_mask is 0, both ESP8266 station and soft-AP will not - * send data in the fixed rate. - * @attention 3. ESP8266 station and soft-AP share the same rate, they can not be - * set into the different rate. - * - * @param uint8 enable_mask : 0x00 - disable the fixed rate - * - 0x01 - use the fixed rate on ESP8266 station - * - 0x02 - use the fixed rate on ESP8266 soft-AP - * - 0x03 - use the fixed rate on ESP8266 station and soft-AP - * @param uint8 rate : value of the fixed rate - * - * @return 0 : succeed - * @return otherwise : fail - */ -sint32 wifi_set_user_fixed_rate(uint8 enable_mask, uint8 rate); - -/** - * @brief Get the fixed rate and mask of ESP8266. - * - * @param uint8 *enable_mask : pointer of the enable_mask - * @param uint8 *rate : pointer of the fixed rate - * - * @return 0 : succeed - * @return otherwise : fail - */ -int wifi_get_user_fixed_rate(uint8 *enable_mask, uint8 *rate); - -enum support_rate { - RATE_11B5M = 0, - RATE_11B11M = 1, - RATE_11B1M = 2, - RATE_11B2M = 3, - RATE_11G6M = 4, - RATE_11G12M = 5, - RATE_11G24M = 6, - RATE_11G48M = 7, - RATE_11G54M = 8, - RATE_11G9M = 9, - RATE_11G18M = 10, - RATE_11G36M = 11 -}; - -/** - * @brief Set the support rate of ESP8266. - * - * Set the rate range in the IE of support rate in ESP8266's beacon, - * probe req/resp and other packets. - * Tell other devices about the rate range supported by ESP8266 to limit - * the rate of sending packets from other devices. - * Example : wifi_set_user_sup_rate(RATE_11G6M, RATE_11G24M); - * - * @attention This API can only support 802.11g now, but it will support 802.11b in next version. - * - * @param uint8 min : the minimum value of the support rate, according to enum support_rate. - * @param uint8 max : the maximum value of the support rate, according to enum support_rate. - * - * @return 0 : succeed - * @return otherwise : fail - */ -sint32 wifi_set_user_sup_rate(uint8 min, uint8 max); - -enum RATE_11B_ID { - RATE_11B_B11M = 0, - RATE_11B_B5M = 1, - RATE_11B_B2M = 2, - RATE_11B_B1M = 3 -}; - -enum RATE_11G_ID { - RATE_11G_G54M = 0, - RATE_11G_G48M = 1, - RATE_11G_G36M = 2, - RATE_11G_G24M = 3, - RATE_11G_G18M = 4, - RATE_11G_G12M = 5, - RATE_11G_G9M = 6, - RATE_11G_G6M = 7, - RATE_11G_B5M = 8, - RATE_11G_B2M = 9, - RATE_11G_B1M = 10 -}; - -enum RATE_11N_ID { - RATE_11N_MCS7S = 0, - RATE_11N_MCS7 = 1, - RATE_11N_MCS6 = 2, - RATE_11N_MCS5 = 3, - RATE_11N_MCS4 = 4, - RATE_11N_MCS3 = 5, - RATE_11N_MCS2 = 6, - RATE_11N_MCS1 = 7, - RATE_11N_MCS0 = 8, - RATE_11N_B5M = 9, - RATE_11N_B2M = 10, - RATE_11N_B1M = 11 -}; - -#define RC_LIMIT_11B 0 -#define RC_LIMIT_11G 1 -#define RC_LIMIT_11N 2 -#define RC_LIMIT_P2P_11G 3 -#define RC_LIMIT_P2P_11N 4 -#define RC_LIMIT_NUM 5 - -#define LIMIT_RATE_MASK_NONE 0x00 -#define LIMIT_RATE_MASK_STA 0x01 -#define LIMIT_RATE_MASK_AP 0x02 -#define LIMIT_RATE_MASK_ALL 0x03 - -/** - * @brief Limit the initial rate of sending data from ESP8266. - * - * Example: - * wifi_set_user_rate_limit(RC_LIMIT_11G, 0, RATE_11G_G18M, RATE_11G_G6M); - * - * @attention The rate of retransmission is not limited by this API. - * - * @param uint8 mode : WiFi mode - * - #define RC_LIMIT_11B 0 - * - #define RC_LIMIT_11G 1 - * - #define RC_LIMIT_11N 2 - * @param uint8 ifidx : interface of ESP8266 - * - 0x00 - ESP8266 station - * - 0x01 - ESP8266 soft-AP - * @param uint8 max : the maximum value of the rate, according to the enum rate - * corresponding to the first parameter mode. - * @param uint8 min : the minimum value of the rate, according to the enum rate - * corresponding to the first parameter mode. - * - * @return 0 : succeed - * @return otherwise : fail - */ -bool wifi_set_user_rate_limit(uint8 mode, uint8 ifidx, uint8 max, uint8 min); - -/** - * @brief Get the interfaces of ESP8266 whose rate of sending data is limited by - * wifi_set_user_rate_limit. - * - * @param null - * - * @return LIMIT_RATE_MASK_NONE - disable the limitation on both ESP8266 station and soft-AP - * @return LIMIT_RATE_MASK_STA - enable the limitation on ESP8266 station - * @return LIMIT_RATE_MASK_AP - enable the limitation on ESP8266 soft-AP - * @return LIMIT_RATE_MASK_ALL - enable the limitation on both ESP8266 station and soft-AP - */ -uint8 wifi_get_user_limit_rate_mask(void); - -/** - * @brief Set the interfaces of ESP8266 whose rate of sending packets is limited by - * wifi_set_user_rate_limit. - * - * @param uint8 enable_mask : - * - LIMIT_RATE_MASK_NONE - disable the limitation on both ESP8266 station and soft-AP - * - LIMIT_RATE_MASK_STA - enable the limitation on ESP8266 station - * - LIMIT_RATE_MASK_AP - enable the limitation on ESP8266 soft-AP - * - LIMIT_RATE_MASK_ALL - enable the limitation on both ESP8266 station and soft-AP - * - * @return true : succeed - * @return false : fail - */ -bool wifi_set_user_limit_rate_mask(uint8 enable_mask); - -/** - * @} - */ - - -/** \defgroup WiFi_User_IE_APIs User IE APIs - * @brief WiFi User IE APIs - */ - -/** @addtogroup WiFi_User_IE_APIs - * @{ - */ - -typedef enum { - USER_IE_BEACON = 0, - USER_IE_PROBE_REQ, - USER_IE_PROBE_RESP, - USER_IE_ASSOC_REQ, - USER_IE_ASSOC_RESP, - USER_IE_MAX -} user_ie_type; - -/** - * @brief User IE received callback. - * - * @param user_ie_type type : type of user IE. - * @param const uint8 sa[6] : source address of the packet. - * @param const uint8 m_oui[3] : factory tag. - * @param uint8 *user_ie : pointer of user IE. - * @param uint8 ie_len : length of user IE. - * @param sint32 rssi : signal strength. - * - * @return null - */ -typedef void (*user_ie_manufacturer_recv_cb_t)(user_ie_type type, const uint8 sa[6], const uint8 m_oui[3], uint8 *ie, uint8 ie_len, sint32 rssi); - -/** - * @brief Set user IE of ESP8266. - * - * The user IE will be added to the target packets of user_ie_type. - * - * @param bool enable : - * - true, enable the corresponding user IE function, all parameters below have to be set. - * - false, disable the corresponding user IE function and release the resource, - * only the parameter "type" below has to be set. - * @param uint8 *m_oui : factory tag, apply for it from Espressif System. - * @param user_ie_type type : IE type. If it is USER_IE_BEACON, please disable the - * IE function and enable again to take the configuration - * effect immediately . - * @param uint8 *user_ie : user-defined information elements, need not input the whole - * 802.11 IE, need only the user-define part. - * @param uint8 len : length of user IE, 247 bytes at most. - * - * @return true : succeed - * @return false : fail - */ - -bool wifi_set_user_ie(bool enable, uint8 *m_oui, user_ie_type type, uint8 *user_ie, uint8 len); - -/** - * @brief Register user IE received callback. - * - * @param user_ie_manufacturer_recv_cb_t cb : callback - * - * @return 0 : succeed - * @return -1 : fail - */ -sint32 wifi_register_user_ie_manufacturer_recv_cb(user_ie_manufacturer_recv_cb_t cb); - -/** - * @brief Unregister user IE received callback. - * - * @param null - * - * @return null - */ -void wifi_unregister_user_ie_manufacturer_recv_cb(void); - -/** - * @} - */ - -/** \defgroup WiFi_Sniffer_APIs Sniffer APIs - * @brief WiFi sniffer APIs - */ - -/** @addtogroup WiFi_Sniffer_APIs - * @{ - */ - -/** - * @brief The RX callback function in the promiscuous mode. - * - * Each time a packet is received, the callback function will be called. - * - * @param uint8 *buf : the data received - * @param uint16 len : data length - * - * @return null - */ -typedef void (* wifi_promiscuous_cb_t)(uint8 *buf, uint16 len); - -/** - * @brief Register the RX callback function in the promiscuous mode. - * - * Each time a packet is received, the registered callback function will be called. - * - * @param wifi_promiscuous_cb_t cb : callback - * - * @return null - */ -void wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb); - -/** - * @brief Get the channel number for sniffer functions. - * - * @param null - * - * @return channel number - */ -uint8 wifi_get_channel(void); - -/** - * @brief Set the channel number for sniffer functions. - * - * @param uint8 channel : channel number - * - * @return true : succeed - * @return false : fail - */ -bool wifi_set_channel(uint8 channel); - -/** - * @brief Set the MAC address filter for the sniffer mode. - * - * @attention This filter works only for the current sniffer mode. - * If users disable and then enable the sniffer mode, and then enable - * sniffer, they need to set the MAC address filter again. - * - * @param const uint8_t *address : MAC address - * - * @return true : succeed - * @return false : fail - */ -bool wifi_promiscuous_set_mac(const uint8_t *address); - -/** - * @brief Enable the promiscuous mode. - * - * @attention 1. The promiscuous mode can only be enabled in the ESP8266 station mode. Do not call this API in user_init. - * @attention 2. When in the promiscuous mode, the ESP8266 station and soft-AP are disabled. - * @attention 3. Call wifi_station_disconnect to disconnect before enabling the promiscuous mode. - * @attention 4. Don't call any other APIs when in the promiscuous mode. Call - * wifi_promiscuous_enable(0) to quit sniffer before calling other APIs. - * - * @param uint8 promiscuous : - * - 0: to disable the promiscuous mode - * - 1: to enable the promiscuous mode - * - * @return null - */ -void wifi_promiscuous_enable(uint8 promiscuous); - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __ESP_WIFI_H__ +#define __ESP_WIFI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup WiFi_APIs WiFi Related APIs + * @brief WiFi APIs + */ + +/** @addtogroup WiFi_APIs + * @{ + */ + +/** \defgroup WiFi_Common_APIs Common APIs + * @brief WiFi common APIs + * + * The Flash system parameter area is the last 16KB of the Flash. + * + */ + +/** @addtogroup WiFi_Common_APIs + * @{ + */ + +typedef enum { + NULL_MODE = 0, /**< null mode */ + STATION_MODE, /**< WiFi station mode */ + SOFTAP_MODE, /**< WiFi soft-AP mode */ + STATIONAP_MODE, /**< WiFi station + soft-AP mode */ + MAX_MODE +} WIFI_MODE; + +typedef enum { + AUTH_OPEN = 0, /**< authenticate mode : open */ + AUTH_WEP, /**< authenticate mode : WEP */ + AUTH_WPA_PSK, /**< authenticate mode : WPA_PSK */ + AUTH_WPA2_PSK, /**< authenticate mode : WPA2_PSK */ + AUTH_WPA_WPA2_PSK, /**< authenticate mode : WPA_WPA2_PSK */ + AUTH_MAX +} AUTH_MODE; + +/** + * @brief Get the current operating mode of the WiFi. + * + * @param null + * + * @return WiFi operating modes: + * - 0x01: station mode; + * - 0x02: soft-AP mode + * - 0x03: station+soft-AP mode + */ +WIFI_MODE wifi_get_opmode(void); + +/** + * @brief Get the operating mode of the WiFi saved in the Flash. + * + * @param null + * + * @return WiFi operating modes: + * - 0x01: station mode; + * - 0x02: soft-AP mode + * - 0x03: station+soft-AP mode + */ +WIFI_MODE wifi_get_opmode_default(void); + +/** + * @brief Set the WiFi operating mode, and save it to Flash. + * + * Set the WiFi operating mode as station, soft-AP or station+soft-AP, + * and save it to Flash. The default mode is soft-AP mode. + * + * @attention This configuration will be saved in the Flash system parameter area if changed. + * + * @param uint8 opmode : WiFi operating modes: + * - 0x01: station mode; + * - 0x02: soft-AP mode + * - 0x03: station+soft-AP mode + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_opmode(WIFI_MODE opmode); + +/** + * @brief Set the WiFi operating mode, and will not save it to Flash. + * + * Set the WiFi operating mode as station, soft-AP or station+soft-AP, and + * the mode won't be saved to the Flash. + * + * @param uint8 opmode : WiFi operating modes: + * - 0x01: station mode; + * - 0x02: soft-AP mode + * - 0x03: station+soft-AP mode + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_opmode_current(WIFI_MODE opmode); + +typedef enum { + STATION_IF = 0, /**< ESP8266 station interface */ + SOFTAP_IF, /**< ESP8266 soft-AP interface */ + MAX_IF +} WIFI_INTERFACE; + +struct ip_info { + struct ip_addr ip; /**< IP address */ + struct ip_addr netmask; /**< netmask */ + struct ip_addr gw; /**< gateway */ +}; + +/** + * @brief Get the IP address of the ESP8266 WiFi station or the soft-AP interface. + * + * @attention Users need to enable the target interface (station or soft-AP) by wifi_set_opmode first. + * + * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, + * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. + * @param struct ip_info *info : the IP information obtained. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_get_ip_info(WIFI_INTERFACE if_index, struct ip_info *info); + +/** + * @brief Set the IP address of the ESP8266 WiFi station or the soft-AP interface. + * + * @attention 1. Users need to enable the target interface (station or soft-AP) by + * wifi_set_opmode first. + * @attention 2. To set static IP, users need to disable DHCP first (wifi_station_dhcpc_stop + * or wifi_softap_dhcps_stop): + * - If the DHCP is enabled, the static IP will be disabled; if the static IP is enabled, + * the DHCP will be disabled. It depends on the latest configuration. + * + * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, + * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. + * @param struct ip_info *info : the IP information obtained. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_ip_info(WIFI_INTERFACE if_index, struct ip_info *info); + +/** + * @brief Get MAC address of the ESP8266 WiFi station or the soft-AP interface. + * + * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, + * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. + * @param uint8 *macaddr : the MAC address. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_get_macaddr(WIFI_INTERFACE if_index, uint8 *macaddr); + +/** + * @brief Set MAC address of the ESP8266 WiFi station or the soft-AP interface. + * + * @attention 1. This API can only be called in user_init. + * @attention 2. Users need to enable the target interface (station or soft-AP) by wifi_set_opmode first. + * @attention 3. ESP8266 soft-AP and station have different MAC addresses, do not set them to be the same. + * - The bit0 of the first byte of ESP8266 MAC address can not be 1. For example, the MAC address + * can set to be "1a:XX:XX:XX:XX:XX", but can not be "15:XX:XX:XX:XX:XX". + * + * @param WIFI_INTERFACE if_index : get the IP address of the station or the soft-AP interface, + * 0x00 for STATION_IF, 0x01 for SOFTAP_IF. + * @param uint8 *macaddr : the MAC address. + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_macaddr(WIFI_INTERFACE if_index, uint8 *macaddr); + +/** + * @brief Install the WiFi status LED. + * + * @param uint8 gpio_id : GPIO ID + * @param uint8 gpio_name : GPIO mux name + * @param uint8 gpio_func : GPIO function + * + * @return null + */ +void wifi_status_led_install(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func); + +/** + * @brief Uninstall the WiFi status LED. + * + * @param null + * + * @return null + */ +void wifi_status_led_uninstall(void); + +typedef enum { + PHY_MODE_11B = 1, /**< 802.11b */ + PHY_MODE_11G = 2, /**< 802.11g */ + PHY_MODE_11N = 3 /**< 802.11n */ +} WIFI_PHY_MODE; + +/** + * @brief Get the ESP8266 physical mode (802.11b/g/n). + * + * @param null + * + * @return enum WIFI_PHY_MODE + */ +WIFI_PHY_MODE wifi_get_phy_mode(void); + +/** + * @brief Set the ESP8266 physical mode (802.11b/g/n). + * + * @attention The ESP8266 soft-AP only supports bg. + * + * @param WIFI_PHY_MODE mode : physical mode + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_phy_mode(WIFI_PHY_MODE mode); + +typedef enum { + EVENT_STAMODE_SCAN_DONE = 0, /**< ESP8266 station finish scanning AP */ + EVENT_STAMODE_CONNECTED, /**< ESP8266 station connected to AP */ + EVENT_STAMODE_DISCONNECTED, /**< ESP8266 station disconnected to AP */ + EVENT_STAMODE_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP8266 station changed */ + EVENT_STAMODE_GOT_IP, /**< ESP8266 station got IP from connected AP */ + EVENT_STAMODE_DHCP_TIMEOUT, /**< ESP8266 station dhcp client got IP timeout */ + EVENT_SOFTAPMODE_STACONNECTED, /**< a station connected to ESP8266 soft-AP */ + EVENT_SOFTAPMODE_STADISCONNECTED, /**< a station disconnected to ESP8266 soft-AP */ + EVENT_SOFTAPMODE_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */ + EVENT_MAX +} SYSTEM_EVENT; + +enum { + REASON_UNSPECIFIED = 1, + REASON_AUTH_EXPIRE = 2, + REASON_AUTH_LEAVE = 3, + REASON_ASSOC_EXPIRE = 4, + REASON_ASSOC_TOOMANY = 5, + REASON_NOT_AUTHED = 6, + REASON_NOT_ASSOCED = 7, + REASON_ASSOC_LEAVE = 8, + REASON_ASSOC_NOT_AUTHED = 9, + REASON_DISASSOC_PWRCAP_BAD = 10, + REASON_DISASSOC_SUPCHAN_BAD = 11, + REASON_IE_INVALID = 13, + REASON_MIC_FAILURE = 14, + REASON_4WAY_HANDSHAKE_TIMEOUT = 15, + REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, + REASON_IE_IN_4WAY_DIFFERS = 17, + REASON_GROUP_CIPHER_INVALID = 18, + REASON_PAIRWISE_CIPHER_INVALID = 19, + REASON_AKMP_INVALID = 20, + REASON_UNSUPP_RSN_IE_VERSION = 21, + REASON_INVALID_RSN_IE_CAP = 22, + REASON_802_1X_AUTH_FAILED = 23, + REASON_CIPHER_SUITE_REJECTED = 24, + + REASON_BEACON_TIMEOUT = 200, + REASON_NO_AP_FOUND = 201, + REASON_AUTH_FAIL = 202, + REASON_ASSOC_FAIL = 203, + REASON_HANDSHAKE_TIMEOUT = 204, +}; + +typedef struct { + uint32 status; /**< status of scanning APs*/ + struct bss_info *bss; /**< list of APs found*/ +} Event_StaMode_ScanDone_t; + +typedef struct { + uint8 ssid[32]; /**< SSID of connected AP */ + uint8 ssid_len; /**< SSID length of connected AP */ + uint8 bssid[6]; /**< BSSID of connected AP*/ + uint8 channel; /**< channel of connected AP*/ +} Event_StaMode_Connected_t; + +typedef struct { + uint8 ssid[32]; /**< SSID of disconnected AP */ + uint8 ssid_len; /**< SSID length of disconnected AP */ + uint8 bssid[6]; /**< BSSID of disconnected AP */ + uint8 reason; /**< reason of disconnection */ +} Event_StaMode_Disconnected_t; + +typedef struct { + uint8 old_mode; /**< the old auth mode of AP */ + uint8 new_mode; /**< the new auth mode of AP */ +} Event_StaMode_AuthMode_Change_t; + +typedef struct { + struct ip_addr ip; /**< IP address that ESP8266 station got from connected AP */ + struct ip_addr mask; /**< netmask that ESP8266 station got from connected AP */ + struct ip_addr gw; /**< gateway that ESP8266 station got from connected AP */ +} Event_StaMode_Got_IP_t; + +typedef struct { + uint8 mac[6]; /**< MAC address of the station connected to ESP8266 soft-AP */ + uint8 aid; /**< the aid that ESP8266 soft-AP gives to the station connected to */ +} Event_SoftAPMode_StaConnected_t; + +typedef struct { + uint8 mac[6]; /**< MAC address of the station disconnects to ESP8266 soft-AP */ + uint8 aid; /**< the aid that ESP8266 soft-AP gave to the station disconnects to */ +} Event_SoftAPMode_StaDisconnected_t; + +typedef struct { + int rssi; /**< Received probe request signal strength */ + uint8 mac[6]; /**< MAC address of the station which send probe request */ +} Event_SoftAPMode_ProbeReqRecved_t; + +typedef union { + Event_StaMode_ScanDone_t scan_done; /**< ESP8266 station scan (APs) done */ + Event_StaMode_Connected_t connected; /**< ESP8266 station connected to AP */ + Event_StaMode_Disconnected_t disconnected; /**< ESP8266 station disconnected to AP */ + Event_StaMode_AuthMode_Change_t auth_change; /**< the auth mode of AP ESP8266 station connected to changed */ + Event_StaMode_Got_IP_t got_ip; /**< ESP8266 station got IP */ + Event_SoftAPMode_StaConnected_t sta_connected; /**< a station connected to ESP8266 soft-AP */ + Event_SoftAPMode_StaDisconnected_t sta_disconnected; /**< a station disconnected to ESP8266 soft-AP */ + Event_SoftAPMode_ProbeReqRecved_t ap_probereqrecved; /**< ESP8266 softAP receive probe request packet */ +} Event_Info_u; + +typedef struct _esp_event { + SYSTEM_EVENT event_id; /**< even ID */ + Event_Info_u event_info; /**< event information */ +} System_Event_t; + +/** + * @brief The Wi-Fi event handler. + * + * @attention No complex operations are allowed in callback. + * If users want to execute any complex operations, please post message to another task instead. + * + * @param System_Event_t *event : WiFi event + * + * @return null + */ +typedef void (* wifi_event_handler_cb_t)(System_Event_t *event); + +/** + * @brief Register the Wi-Fi event handler. + * + * @param wifi_event_handler_cb_t cb : callback function + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_event_handler_cb(wifi_event_handler_cb_t cb); + +/** + * @brief Callback of sending user-define 802.11 packets. + * + * @param uint8 status : 0, packet sending succeed; otherwise, fail. + * + * @return null + */ +typedef void (*freedom_outside_cb_t)(uint8 status); + +/** + * @brief Register a callback for sending user-define 802.11 packets. + * + * @attention Only after the previous packet was sent, entered the freedom_outside_cb_t, + * the next packet is allowed to send. + * + * @param freedom_outside_cb_t cb : sent callback + * + * @return 0, succeed; + * @return -1, fail. + */ +sint32 wifi_register_send_pkt_freedom_cb(freedom_outside_cb_t cb); + +/** + * @brief Unregister the callback for sending user-define 802.11 packets. + * + * @param null + * + * @return null + */ +void wifi_unregister_send_pkt_freedom_cb(void); + +/** + * @brief Send user-define 802.11 packets. + * + * @attention 1. Packet has to be the whole 802.11 packet, does not include the FCS. + * The length of the packet has to be longer than the minimum length + * of the header of 802.11 packet which is 24 bytes, and less than 1400 bytes. + * @attention 2. Duration area is invalid for user, it will be filled in SDK. + * @attention 3. The rate of sending packet is same as the management packet which + * is the same as the system rate of sending packets. + * @attention 4. Only after the previous packet was sent, entered the sent callback, + * the next packet is allowed to send. Otherwise, wifi_send_pkt_freedom + * will return fail. + * + * @param uint8 *buf : pointer of packet + * @param uint16 len : packet length + * @param bool sys_seq : follow the system's 802.11 packets sequence number or not, + * if it is true, the sequence number will be increased 1 every + * time a packet sent. + * + * @return 0, succeed; + * @return -1, fail. + */ +sint32 wifi_send_pkt_freedom(uint8 *buf, uint16 len, bool sys_seq); + +/** + * @brief Enable RFID LOCP (Location Control Protocol) to receive WDS packets. + * + * @param null + * + * @return 0, succeed; + * @return otherwise, fail. + */ +sint32 wifi_rfid_locp_recv_open(void); + +/** + * @brief Disable RFID LOCP (Location Control Protocol) . + * + * @param null + * + * @return null + */ +void wifi_rfid_locp_recv_close(void); + +/** + * @brief RFID LOCP (Location Control Protocol) receive callback . + * + * @param uint8 *frm : point to the head of 802.11 packet + * @param int len : packet length + * @param int rssi : signal strength + * + * @return null + */ +typedef void (*rfid_locp_cb_t)(uint8 *frm, int len, sint8 rssi); + +/** + * @brief Register a callback of receiving WDS packets. + * + * Register a callback of receiving WDS packets. Only if the first MAC + * address of the WDS packet is a multicast address. + * + * @param rfid_locp_cb_t cb : callback + * + * @return 0, succeed; + * @return otherwise, fail. + */ +sint32 wifi_register_rfid_locp_recv_cb(rfid_locp_cb_t cb); + +/** + * @brief Unregister the callback of receiving WDS packets. + * + * @param null + * + * @return null + */ +void wifi_unregister_rfid_locp_recv_cb(void); + +typedef enum { + NONE_SLEEP_T = 0, + LIGHT_SLEEP_T, + MODEM_SLEEP_T +} sleep_type; + +/** + * @brief Sets sleep type. + * + * Set NONE_SLEEP_T to disable sleep. Default to be Modem sleep. + * + * @attention Sleep function only takes effect in station-only mode. + * + * @param sleep_type type : sleep type + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_sleep_type(sleep_type type); + +/** + * @brief Gets sleep type. + * + * @param null + * + * @return sleep type + */ +sleep_type wifi_get_sleep_type(void); + +/** + * @} + */ + + +/** \defgroup WiFi_Force_Sleep_APIs Force Sleep APIs + * @brief WiFi Force Sleep APIs + */ + +/** @addtogroup WiFi_Force_Sleep_APIs + * @{ + */ + +/** + * @brief Enable force sleep function. + * + * @attention Force sleep function is disabled by default. + * + * @param null + * + * @return null + */ +void wifi_fpm_open(void); + +/** + * @brief Disable force sleep function. + * + * @param null + * + * @return null + */ +void wifi_fpm_close(void); + +/** + * @brief Wake ESP8266 up from MODEM_SLEEP_T force sleep. + * + * @attention This API can only be called when MODEM_SLEEP_T force sleep function + * is enabled, after calling wifi_fpm_open. + * This API can not be called after calling wifi_fpm_close. + * + * @param null + * + * @return null + */ +void wifi_fpm_do_wakeup(void); + +typedef void (*fpm_wakeup_cb)(void); + +/** + * @brief Set a callback of waken up from force sleep because of time out. + * + * @attention 1. This API can only be called when force sleep function is enabled, + * after calling wifi_fpm_open. This API can not be called after calling + * wifi_fpm_close. + * @attention 2. fpm_wakeup_cb_func will be called after system woke up only if the + * force sleep time out (wifi_fpm_do_sleep and the parameter is not 0xFFFFFFF). + * @attention 3. fpm_wakeup_cb_func will not be called if woke up by wifi_fpm_do_wakeup + * from MODEM_SLEEP_T type force sleep. + * + * @param void (*fpm_wakeup_cb_func)(void) : callback of waken up + * + * @return null + */ +void wifi_fpm_set_wakeup_cb(fpm_wakeup_cb cb); + +/** + * @brief Force ESP8266 enter sleep mode, and it will wake up automatically when time out. + * + * @attention 1. This API can only be called when force sleep function is enabled, after + * calling wifi_fpm_open. This API can not be called after calling wifi_fpm_close. + * @attention 2. If this API returned 0 means that the configuration is set successfully, + * but the ESP8266 will not enter sleep mode immediately, it is going to sleep + * in the system idle task. Please do not call other WiFi related function right + * after calling this API. + * + * @param uint32 sleep_time_in_us : sleep time, ESP8266 will wake up automatically + * when time out. Unit: us. Range: 10000 ~ 268435455(0xFFFFFFF). + * - If sleep_time_in_us is 0xFFFFFFF, the ESP8266 will sleep till + * - if wifi_fpm_set_sleep_type is set to be LIGHT_SLEEP_T, ESP8266 can wake up by GPIO. + * - if wifi_fpm_set_sleep_type is set to be MODEM_SLEEP_T, ESP8266 can wake up by wifi_fpm_do_wakeup. + * + * @return 0, setting succeed; + * @return -1, fail to sleep, sleep status error; + * @return -2, fail to sleep, force sleep function is not enabled. + */ +sint8 wifi_fpm_do_sleep(uint32 sleep_time_in_us); + +/** + * @brief Set sleep type for force sleep function. + * + * @attention This API can only be called before wifi_fpm_open. + * + * @param sleep_type type : sleep type + * + * @return null + */ +void wifi_fpm_set_sleep_type(sleep_type type); + +/** + * @brief Get sleep type of force sleep function. + * + * @param null + * + * @return sleep type + */ +sleep_type wifi_fpm_get_sleep_type(void); + +/** + * @} + */ + +/** \defgroup WiFi_Rate_Control_APIs Rate Control APIs + * @brief WiFi Rate Control APIs + */ + +/** @addtogroup WiFi_Rate_Control_APIs + * @{ + */ + +enum FIXED_RATE { + PHY_RATE_48 = 0x8, + PHY_RATE_24 = 0x9, + PHY_RATE_12 = 0xA, + PHY_RATE_6 = 0xB, + PHY_RATE_54 = 0xC, + PHY_RATE_36 = 0xD, + PHY_RATE_18 = 0xE, + PHY_RATE_9 = 0xF +}; + +#define FIXED_RATE_MASK_NONE 0x00 +#define FIXED_RATE_MASK_STA 0x01 +#define FIXED_RATE_MASK_AP 0x02 +#define FIXED_RATE_MASK_ALL 0x03 + +/** + * @brief Set the fixed rate and mask of sending data from ESP8266. + * + * @attention 1. Only if the corresponding bit in enable_mask is 1, ESP8266 station + * or soft-AP will send data in the fixed rate. + * @attention 2. If the enable_mask is 0, both ESP8266 station and soft-AP will not + * send data in the fixed rate. + * @attention 3. ESP8266 station and soft-AP share the same rate, they can not be + * set into the different rate. + * + * @param uint8 enable_mask : 0x00 - disable the fixed rate + * - 0x01 - use the fixed rate on ESP8266 station + * - 0x02 - use the fixed rate on ESP8266 soft-AP + * - 0x03 - use the fixed rate on ESP8266 station and soft-AP + * @param uint8 rate : value of the fixed rate + * + * @return 0 : succeed + * @return otherwise : fail + */ +sint32 wifi_set_user_fixed_rate(uint8 enable_mask, uint8 rate); + +/** + * @brief Get the fixed rate and mask of ESP8266. + * + * @param uint8 *enable_mask : pointer of the enable_mask + * @param uint8 *rate : pointer of the fixed rate + * + * @return 0 : succeed + * @return otherwise : fail + */ +int wifi_get_user_fixed_rate(uint8 *enable_mask, uint8 *rate); + +enum support_rate { + RATE_11B5M = 0, + RATE_11B11M = 1, + RATE_11B1M = 2, + RATE_11B2M = 3, + RATE_11G6M = 4, + RATE_11G12M = 5, + RATE_11G24M = 6, + RATE_11G48M = 7, + RATE_11G54M = 8, + RATE_11G9M = 9, + RATE_11G18M = 10, + RATE_11G36M = 11 +}; + +/** + * @brief Set the support rate of ESP8266. + * + * Set the rate range in the IE of support rate in ESP8266's beacon, + * probe req/resp and other packets. + * Tell other devices about the rate range supported by ESP8266 to limit + * the rate of sending packets from other devices. + * Example : wifi_set_user_sup_rate(RATE_11G6M, RATE_11G24M); + * + * @attention This API can only support 802.11g now, but it will support 802.11b in next version. + * + * @param uint8 min : the minimum value of the support rate, according to enum support_rate. + * @param uint8 max : the maximum value of the support rate, according to enum support_rate. + * + * @return 0 : succeed + * @return otherwise : fail + */ +sint32 wifi_set_user_sup_rate(uint8 min, uint8 max); + +enum RATE_11B_ID { + RATE_11B_B11M = 0, + RATE_11B_B5M = 1, + RATE_11B_B2M = 2, + RATE_11B_B1M = 3 +}; + +enum RATE_11G_ID { + RATE_11G_G54M = 0, + RATE_11G_G48M = 1, + RATE_11G_G36M = 2, + RATE_11G_G24M = 3, + RATE_11G_G18M = 4, + RATE_11G_G12M = 5, + RATE_11G_G9M = 6, + RATE_11G_G6M = 7, + RATE_11G_B5M = 8, + RATE_11G_B2M = 9, + RATE_11G_B1M = 10 +}; + +enum RATE_11N_ID { + RATE_11N_MCS7S = 0, + RATE_11N_MCS7 = 1, + RATE_11N_MCS6 = 2, + RATE_11N_MCS5 = 3, + RATE_11N_MCS4 = 4, + RATE_11N_MCS3 = 5, + RATE_11N_MCS2 = 6, + RATE_11N_MCS1 = 7, + RATE_11N_MCS0 = 8, + RATE_11N_B5M = 9, + RATE_11N_B2M = 10, + RATE_11N_B1M = 11 +}; + +#define RC_LIMIT_11B 0 +#define RC_LIMIT_11G 1 +#define RC_LIMIT_11N 2 +#define RC_LIMIT_P2P_11G 3 +#define RC_LIMIT_P2P_11N 4 +#define RC_LIMIT_NUM 5 + +#define LIMIT_RATE_MASK_NONE 0x00 +#define LIMIT_RATE_MASK_STA 0x01 +#define LIMIT_RATE_MASK_AP 0x02 +#define LIMIT_RATE_MASK_ALL 0x03 + +/** + * @brief Limit the initial rate of sending data from ESP8266. + * + * Example: + * wifi_set_user_rate_limit(RC_LIMIT_11G, 0, RATE_11G_G18M, RATE_11G_G6M); + * + * @attention The rate of retransmission is not limited by this API. + * + * @param uint8 mode : WiFi mode + * - #define RC_LIMIT_11B 0 + * - #define RC_LIMIT_11G 1 + * - #define RC_LIMIT_11N 2 + * @param uint8 ifidx : interface of ESP8266 + * - 0x00 - ESP8266 station + * - 0x01 - ESP8266 soft-AP + * @param uint8 max : the maximum value of the rate, according to the enum rate + * corresponding to the first parameter mode. + * @param uint8 min : the minimum value of the rate, according to the enum rate + * corresponding to the first parameter mode. + * + * @return 0 : succeed + * @return otherwise : fail + */ +bool wifi_set_user_rate_limit(uint8 mode, uint8 ifidx, uint8 max, uint8 min); + +/** + * @brief Get the interfaces of ESP8266 whose rate of sending data is limited by + * wifi_set_user_rate_limit. + * + * @param null + * + * @return LIMIT_RATE_MASK_NONE - disable the limitation on both ESP8266 station and soft-AP + * @return LIMIT_RATE_MASK_STA - enable the limitation on ESP8266 station + * @return LIMIT_RATE_MASK_AP - enable the limitation on ESP8266 soft-AP + * @return LIMIT_RATE_MASK_ALL - enable the limitation on both ESP8266 station and soft-AP + */ +uint8 wifi_get_user_limit_rate_mask(void); + +/** + * @brief Set the interfaces of ESP8266 whose rate of sending packets is limited by + * wifi_set_user_rate_limit. + * + * @param uint8 enable_mask : + * - LIMIT_RATE_MASK_NONE - disable the limitation on both ESP8266 station and soft-AP + * - LIMIT_RATE_MASK_STA - enable the limitation on ESP8266 station + * - LIMIT_RATE_MASK_AP - enable the limitation on ESP8266 soft-AP + * - LIMIT_RATE_MASK_ALL - enable the limitation on both ESP8266 station and soft-AP + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_user_limit_rate_mask(uint8 enable_mask); + +/** + * @} + */ + + +/** \defgroup WiFi_User_IE_APIs User IE APIs + * @brief WiFi User IE APIs + */ + +/** @addtogroup WiFi_User_IE_APIs + * @{ + */ + +typedef enum { + USER_IE_BEACON = 0, + USER_IE_PROBE_REQ, + USER_IE_PROBE_RESP, + USER_IE_ASSOC_REQ, + USER_IE_ASSOC_RESP, + USER_IE_MAX +} user_ie_type; + +/** + * @brief User IE received callback. + * + * @param user_ie_type type : type of user IE. + * @param const uint8 sa[6] : source address of the packet. + * @param const uint8 m_oui[3] : factory tag. + * @param uint8 *user_ie : pointer of user IE. + * @param uint8 ie_len : length of user IE. + * @param sint32 rssi : signal strength. + * + * @return null + */ +typedef void (*user_ie_manufacturer_recv_cb_t)(user_ie_type type, const uint8 sa[6], const uint8 m_oui[3], uint8 *ie, uint8 ie_len, sint32 rssi); + +/** + * @brief Set user IE of ESP8266. + * + * The user IE will be added to the target packets of user_ie_type. + * + * @param bool enable : + * - true, enable the corresponding user IE function, all parameters below have to be set. + * - false, disable the corresponding user IE function and release the resource, + * only the parameter "type" below has to be set. + * @param uint8 *m_oui : factory tag, apply for it from Espressif System. + * @param user_ie_type type : IE type. If it is USER_IE_BEACON, please disable the + * IE function and enable again to take the configuration + * effect immediately . + * @param uint8 *user_ie : user-defined information elements, need not input the whole + * 802.11 IE, need only the user-define part. + * @param uint8 len : length of user IE, 247 bytes at most. + * + * @return true : succeed + * @return false : fail + */ + +bool wifi_set_user_ie(bool enable, uint8 *m_oui, user_ie_type type, uint8 *user_ie, uint8 len); + +/** + * @brief Register user IE received callback. + * + * @param user_ie_manufacturer_recv_cb_t cb : callback + * + * @return 0 : succeed + * @return -1 : fail + */ +sint32 wifi_register_user_ie_manufacturer_recv_cb(user_ie_manufacturer_recv_cb_t cb); + +/** + * @brief Unregister user IE received callback. + * + * @param null + * + * @return null + */ +void wifi_unregister_user_ie_manufacturer_recv_cb(void); + +/** + * @} + */ + +/** \defgroup WiFi_Sniffer_APIs Sniffer APIs + * @brief WiFi sniffer APIs + */ + +/** @addtogroup WiFi_Sniffer_APIs + * @{ + */ + +/** + * @brief The RX callback function in the promiscuous mode. + * + * Each time a packet is received, the callback function will be called. + * + * @param uint8 *buf : the data received + * @param uint16 len : data length + * + * @return null + */ +typedef void (* wifi_promiscuous_cb_t)(uint8 *buf, uint16 len); + +/** + * @brief Register the RX callback function in the promiscuous mode. + * + * Each time a packet is received, the registered callback function will be called. + * + * @param wifi_promiscuous_cb_t cb : callback + * + * @return null + */ +void wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb); + +/** + * @brief Get the channel number for sniffer functions. + * + * @param null + * + * @return channel number + */ +uint8 wifi_get_channel(void); + +/** + * @brief Set the channel number for sniffer functions. + * + * @param uint8 channel : channel number + * + * @return true : succeed + * @return false : fail + */ +bool wifi_set_channel(uint8 channel); + +/** + * @brief Set the MAC address filter for the sniffer mode. + * + * @attention This filter works only for the current sniffer mode. + * If users disable and then enable the sniffer mode, and then enable + * sniffer, they need to set the MAC address filter again. + * + * @param const uint8_t *address : MAC address + * + * @return true : succeed + * @return false : fail + */ +bool wifi_promiscuous_set_mac(const uint8_t *address); + +/** + * @brief Enable the promiscuous mode. + * + * @attention 1. The promiscuous mode can only be enabled in the ESP8266 station mode. Do not call this API in user_init. + * @attention 2. When in the promiscuous mode, the ESP8266 station and soft-AP are disabled. + * @attention 3. Call wifi_station_disconnect to disconnect before enabling the promiscuous mode. + * @attention 4. Don't call any other APIs when in the promiscuous mode. Call + * wifi_promiscuous_enable(0) to quit sniffer before calling other APIs. + * + * @param uint8 promiscuous : + * - 0: to disable the promiscuous mode + * - 1: to enable the promiscuous mode + * + * @return null + */ +void wifi_promiscuous_enable(uint8 promiscuous); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/espressif/pwm.h b/include/espressif/pwm.h index e10bca26..629c3448 100644 --- a/include/espressif/pwm.h +++ b/include/espressif/pwm.h @@ -1,142 +1,142 @@ -/* - * ESPRSSIF MIT License - * - * Copyright (c) 2015 - * - * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, - * it is 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 __PWM_H__ -#define __PWM_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup Driver_APIs Driver APIs - * @brief Driver APIs - */ - -/** @addtogroup Driver_APIs - * @{ - */ - -/** \defgroup PWM_Driver_APIs PWM Driver APIs - * @brief PWM driver APIs - */ - -/** @addtogroup PWM_Driver_APIs - * @{ - */ - -struct pwm_param { - uint32 period; /**< PWM period */ - uint32 freq; /**< PWM frequency */ - uint32 duty[8]; /**< PWM duty */ -}; - -#define PWM_DEPTH 1023 - -/** - * @brief PWM function initialization, including GPIO, frequency and duty cycle. - * - * @attention This API can be called only once. - * - * @param uint32 period : pwm frequency - * @param uint32 *duty : duty cycle - * @param uint32 pwm_channel_num : PWM channel number - * @param uint32 (*pin_info_list)[3] : GPIO parameter of PWM channel, it is a pointer - * of n x 3 array which defines GPIO register, IO - * reuse of corresponding pin and GPIO number. - * - * @return null - */ -void pwm_init(uint32 period, uint32 *duty, uint32 pwm_channel_num, uint32(*pin_info_list)[3]); - -/** - * @brief Set the duty cycle of a PWM channel. - * - * Set the time that high level signal will last, duty depends on period, - * the maximum value can be 1023. - * - * - * @attention After set configuration, pwm_start needs to be called to take effect. - * - * @param uint32 duty : duty cycle - * @param uint8 channel : PWM channel number - * - * @return null - */ -void pwm_set_duty(uint32 duty, uint8 channel); - -/** - * @brief Get the duty cycle of a PWM channel. - * - * @param uint8 channel : PWM channel number - * - * @return Duty cycle of PWM output. - */ -uint32 pwm_get_duty(uint8 channel); - -/** - * @brief Set PWM period, unit : us. - * - * For example, for 1KHz PWM, period is 1000 us. - * - * @attention After set configuration, pwm_start needs to be called to take effect. - * - * @param uint32 period : PWM period, unit : us. - * - * @return null - */ -void pwm_set_period(uint32 period); - -/** - * @brief Get PWM period, unit : us. - * - * @param null - * - * @return PWM period, unit : us. - */ -uint32 pwm_get_period(void); - -/** - * @brief Starts PWM. - * - * @attention This function needs to be called after PWM configuration is changed. - * - * @param null - * - * @return null - */ -void pwm_start(void); - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is 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 __PWM_H__ +#define __PWM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup Driver_APIs Driver APIs + * @brief Driver APIs + */ + +/** @addtogroup Driver_APIs + * @{ + */ + +/** \defgroup PWM_Driver_APIs PWM Driver APIs + * @brief PWM driver APIs + */ + +/** @addtogroup PWM_Driver_APIs + * @{ + */ + +struct pwm_param { + uint32 period; /**< PWM period */ + uint32 freq; /**< PWM frequency */ + uint32 duty[8]; /**< PWM duty */ +}; + +#define PWM_DEPTH 1023 + +/** + * @brief PWM function initialization, including GPIO, frequency and duty cycle. + * + * @attention This API can be called only once. + * + * @param uint32 period : pwm frequency + * @param uint32 *duty : duty cycle + * @param uint32 pwm_channel_num : PWM channel number + * @param uint32 (*pin_info_list)[3] : GPIO parameter of PWM channel, it is a pointer + * of n x 3 array which defines GPIO register, IO + * reuse of corresponding pin and GPIO number. + * + * @return null + */ +void pwm_init(uint32 period, uint32 *duty, uint32 pwm_channel_num, uint32(*pin_info_list)[3]); + +/** + * @brief Set the duty cycle of a PWM channel. + * + * Set the time that high level signal will last, duty depends on period, + * the maximum value can be 1023. + * + * + * @attention After set configuration, pwm_start needs to be called to take effect. + * + * @param uint32 duty : duty cycle + * @param uint8 channel : PWM channel number + * + * @return null + */ +void pwm_set_duty(uint32 duty, uint8 channel); + +/** + * @brief Get the duty cycle of a PWM channel. + * + * @param uint8 channel : PWM channel number + * + * @return Duty cycle of PWM output. + */ +uint32 pwm_get_duty(uint8 channel); + +/** + * @brief Set PWM period, unit : us. + * + * For example, for 1KHz PWM, period is 1000 us. + * + * @attention After set configuration, pwm_start needs to be called to take effect. + * + * @param uint32 period : PWM period, unit : us. + * + * @return null + */ +void pwm_set_period(uint32 period); + +/** + * @brief Get PWM period, unit : us. + * + * @param null + * + * @return PWM period, unit : us. + */ +uint32 pwm_get_period(void); + +/** + * @brief Starts PWM. + * + * @attention This function needs to be called after PWM configuration is changed. + * + * @param null + * + * @return null + */ +void pwm_start(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/freertos/FreeRTOS.h b/include/freertos/FreeRTOS.h index 624dee49..73ab1ecb 100644 --- a/include/freertos/FreeRTOS.h +++ b/include/freertos/FreeRTOS.h @@ -1,612 +1,612 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -#ifndef INC_FREERTOS_H -#define INC_FREERTOS_H - - -/* - * Include the generic headers required for the FreeRTOS port being used. - */ -#include - -/* Basic FreeRTOS definitions. */ -#include "projdefs.h" - -/* Application specific configuration options. */ -#include "FreeRTOSConfig.h" - -/* configUSE_PORT_OPTIMISED_TASK_SELECTION must be defined before portable.h -is included as it is used by the port layer. */ -#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION - #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#endif - -/* Definitions specific to the port being used. */ -#include "portable.h" - - -/* Defines the prototype to which the application task hook function must -conform. */ -typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); - - - - - -/* - * Check all the required application specific macros have been defined. - * These macros are application specific and (as downloaded) are defined - * within FreeRTOSConfig.h. - */ - -#ifndef configUSE_PREEMPTION - #error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef configUSE_IDLE_HOOK - #error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef configUSE_TICK_HOOK - #error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef configUSE_CO_ROUTINES - #error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef INCLUDE_vTaskPrioritySet - #error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef INCLUDE_uxTaskPriorityGet - #error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef INCLUDE_vTaskDelete - #error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef INCLUDE_vTaskSuspend - #error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef INCLUDE_vTaskDelayUntil - #error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef INCLUDE_vTaskDelay - #error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef configUSE_16_BIT_TICKS - #error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. -#endif - -#ifndef INCLUDE_xTaskGetIdleTaskHandle - #define INCLUDE_xTaskGetIdleTaskHandle 0 -#endif - -#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle - #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 -#endif - -#ifndef INCLUDE_xQueueGetMutexHolder - #define INCLUDE_xQueueGetMutexHolder 0 -#endif - -#ifndef INCLUDE_xSemaphoreGetMutexHolder - #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder -#endif - -#ifndef INCLUDE_pcTaskGetTaskName - #define INCLUDE_pcTaskGetTaskName 0 -#endif - -#ifndef configUSE_APPLICATION_TASK_TAG - #define configUSE_APPLICATION_TASK_TAG 0 -#endif - -#ifndef INCLUDE_uxTaskGetStackHighWaterMark - #define INCLUDE_uxTaskGetStackHighWaterMark 0 -#endif - -#ifndef INCLUDE_eTaskGetState - #define INCLUDE_eTaskGetState 0 -#endif - -#ifndef configUSE_RECURSIVE_MUTEXES - #define configUSE_RECURSIVE_MUTEXES 0 -#endif - -#ifndef configUSE_MUTEXES - #define configUSE_MUTEXES 0 -#endif - -#ifndef configUSE_TIMERS - #define configUSE_TIMERS 0 -#endif - -#ifndef configUSE_COUNTING_SEMAPHORES - #define configUSE_COUNTING_SEMAPHORES 0 -#endif - -#ifndef configUSE_ALTERNATIVE_API - #define configUSE_ALTERNATIVE_API 0 -#endif - -#ifndef portCRITICAL_NESTING_IN_TCB - #define portCRITICAL_NESTING_IN_TCB 0 -#endif - -#ifndef configMAX_TASK_NAME_LEN - #define configMAX_TASK_NAME_LEN 16 -#endif - -#ifndef configIDLE_SHOULD_YIELD - #define configIDLE_SHOULD_YIELD 1 -#endif - -#if configMAX_TASK_NAME_LEN < 1 - #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h -#endif - -#ifndef INCLUDE_xTaskResumeFromISR - #define INCLUDE_xTaskResumeFromISR 1 -#endif - -#ifndef configASSERT - #define configASSERT( x ) - #define configASSERT_DEFINED 0 -#else - #define configASSERT_DEFINED 1 -#endif - -/* The timers module relies on xTaskGetSchedulerState(). */ -#if configUSE_TIMERS == 1 - - #ifndef configTIMER_TASK_PRIORITY - #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. - #endif /* configTIMER_TASK_PRIORITY */ - - #ifndef configTIMER_QUEUE_LENGTH - #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. - #endif /* configTIMER_QUEUE_LENGTH */ - - #ifndef configTIMER_TASK_STACK_DEPTH - #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. - #endif /* configTIMER_TASK_STACK_DEPTH */ - -#endif /* configUSE_TIMERS */ - -#ifndef INCLUDE_xTaskGetSchedulerState - #define INCLUDE_xTaskGetSchedulerState 0 -#endif - -#ifndef INCLUDE_xTaskGetCurrentTaskHandle - #define INCLUDE_xTaskGetCurrentTaskHandle 0 -#endif - - -#ifndef portSET_INTERRUPT_MASK_FROM_ISR - #define portSET_INTERRUPT_MASK_FROM_ISR() 0 -#endif - -#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue -#endif - -#ifndef portCLEAN_UP_TCB - #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB -#endif - -#ifndef portSETUP_TCB - #define portSETUP_TCB( pxTCB ) ( void ) pxTCB -#endif - -#ifndef configQUEUE_REGISTRY_SIZE - #define configQUEUE_REGISTRY_SIZE 0U -#endif - -#if ( configQUEUE_REGISTRY_SIZE < 1 ) - #define vQueueAddToRegistry( xQueue, pcName ) - #define vQueueUnregisterQueue( xQueue ) -#endif - -#ifndef portPOINTER_SIZE_TYPE - #define portPOINTER_SIZE_TYPE unsigned long -#endif - -/* Remove any unused trace macros. */ -#ifndef traceSTART - /* Used to perform any necessary initialisation - for example, open a file - into which trace is to be written. */ - #define traceSTART() -#endif - -#ifndef traceEND - /* Use to close a trace, for example close a file into which trace has been - written. */ - #define traceEND() -#endif - -#ifndef traceTASK_SWITCHED_IN - /* Called after a task has been selected to run. pxCurrentTCB holds a pointer - to the task control block of the selected task. */ - #define traceTASK_SWITCHED_IN() -#endif - -#ifndef traceINCREASE_TICK_COUNT - /* Called before stepping the tick count after waking from tickless idle - sleep. */ - #define traceINCREASE_TICK_COUNT( x ) -#endif - -#ifndef traceLOW_POWER_IDLE_BEGIN - /* Called immediately before entering tickless idle. */ - #define traceLOW_POWER_IDLE_BEGIN() -#endif - -#ifndef traceLOW_POWER_IDLE_END - /* Called when returning to the Idle task after a tickless idle. */ - #define traceLOW_POWER_IDLE_END() -#endif - -#ifndef traceTASK_SWITCHED_OUT - /* Called before a task has been selected to run. pxCurrentTCB holds a pointer - to the task control block of the task being switched out. */ - #define traceTASK_SWITCHED_OUT() -#endif - -#ifndef traceTASK_PRIORITY_INHERIT - /* Called when a task attempts to take a mutex that is already held by a - lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task - that holds the mutex. uxInheritedPriority is the priority the mutex holder - will inherit (the priority of the task that is attempting to obtain the - muted. */ - #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) -#endif - -#ifndef traceTASK_PRIORITY_DISINHERIT - /* Called when a task releases a mutex, the holding of which had resulted in - the task inheriting the priority of a higher priority task. - pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the - mutex. uxOriginalPriority is the task's configured (base) priority. */ - #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) -#endif - -#ifndef traceBLOCKING_ON_QUEUE_RECEIVE - /* Task is about to block because it cannot read from a - queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore - upon which the read was attempted. pxCurrentTCB points to the TCB of the - task that attempted the read. */ - #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) -#endif - -#ifndef traceBLOCKING_ON_QUEUE_SEND - /* Task is about to block because it cannot write to a - queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore - upon which the write was attempted. pxCurrentTCB points to the TCB of the - task that attempted the write. */ - #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) -#endif - -#ifndef configCHECK_FOR_STACK_OVERFLOW - #define configCHECK_FOR_STACK_OVERFLOW 0 -#endif - -/* The following event macros are embedded in the kernel API calls. */ - -#ifndef traceMOVED_TASK_TO_READY_STATE - #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) -#endif - -#ifndef traceQUEUE_CREATE - #define traceQUEUE_CREATE( pxNewQueue ) -#endif - -#ifndef traceQUEUE_CREATE_FAILED - #define traceQUEUE_CREATE_FAILED( ucQueueType ) -#endif - -#ifndef traceCREATE_MUTEX - #define traceCREATE_MUTEX( pxNewQueue ) -#endif - -#ifndef traceCREATE_MUTEX_FAILED - #define traceCREATE_MUTEX_FAILED() -#endif - -#ifndef traceGIVE_MUTEX_RECURSIVE - #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) -#endif - -#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED - #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) -#endif - -#ifndef traceTAKE_MUTEX_RECURSIVE - #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) -#endif - -#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED - #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) -#endif - -#ifndef traceCREATE_COUNTING_SEMAPHORE - #define traceCREATE_COUNTING_SEMAPHORE() -#endif - -#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED - #define traceCREATE_COUNTING_SEMAPHORE_FAILED() -#endif - -#ifndef traceQUEUE_SEND - #define traceQUEUE_SEND( pxQueue ) -#endif - -#ifndef traceQUEUE_SEND_FAILED - #define traceQUEUE_SEND_FAILED( pxQueue ) -#endif - -#ifndef traceQUEUE_RECEIVE - #define traceQUEUE_RECEIVE( pxQueue ) -#endif - -#ifndef traceQUEUE_PEEK - #define traceQUEUE_PEEK( pxQueue ) -#endif - -#ifndef traceQUEUE_PEEK_FROM_ISR - #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) -#endif - -#ifndef traceQUEUE_RECEIVE_FAILED - #define traceQUEUE_RECEIVE_FAILED( pxQueue ) -#endif - -#ifndef traceQUEUE_SEND_FROM_ISR - #define traceQUEUE_SEND_FROM_ISR( pxQueue ) -#endif - -#ifndef traceQUEUE_SEND_FROM_ISR_FAILED - #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) -#endif - -#ifndef traceQUEUE_RECEIVE_FROM_ISR - #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) -#endif - -#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED - #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) -#endif - -#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED - #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) -#endif - -#ifndef traceQUEUE_DELETE - #define traceQUEUE_DELETE( pxQueue ) -#endif - -#ifndef traceTASK_CREATE - #define traceTASK_CREATE( pxNewTCB ) -#endif - -#ifndef traceTASK_CREATE_FAILED - #define traceTASK_CREATE_FAILED() -#endif - -#ifndef traceTASK_DELETE - #define traceTASK_DELETE( pxTaskToDelete ) -#endif - -#ifndef traceTASK_DELAY_UNTIL - #define traceTASK_DELAY_UNTIL() -#endif - -#ifndef traceTASK_DELAY - #define traceTASK_DELAY() -#endif - -#ifndef traceTASK_PRIORITY_SET - #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) -#endif - -#ifndef traceTASK_SUSPEND - #define traceTASK_SUSPEND( pxTaskToSuspend ) -#endif - -#ifndef traceTASK_RESUME - #define traceTASK_RESUME( pxTaskToResume ) -#endif - -#ifndef traceTASK_RESUME_FROM_ISR - #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) -#endif - -#ifndef traceTASK_INCREMENT_TICK - #define traceTASK_INCREMENT_TICK( xTickCount ) -#endif - -#ifndef traceTIMER_CREATE - #define traceTIMER_CREATE( pxNewTimer ) -#endif - -#ifndef traceTIMER_CREATE_FAILED - #define traceTIMER_CREATE_FAILED() -#endif - -#ifndef traceTIMER_COMMAND_SEND - #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) -#endif - -#ifndef traceTIMER_EXPIRED - #define traceTIMER_EXPIRED( pxTimer ) -#endif - -#ifndef traceTIMER_COMMAND_RECEIVED - #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) -#endif - -#ifndef configGENERATE_RUN_TIME_STATS - #define configGENERATE_RUN_TIME_STATS 0 -#endif - -#if ( configGENERATE_RUN_TIME_STATS == 1 ) - - #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS - #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. - #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ - - #ifndef portGET_RUN_TIME_COUNTER_VALUE - #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE - #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. - #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ - #endif /* portGET_RUN_TIME_COUNTER_VALUE */ - -#endif /* configGENERATE_RUN_TIME_STATS */ - -#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS - #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() -#endif - -#ifndef configUSE_MALLOC_FAILED_HOOK - #define configUSE_MALLOC_FAILED_HOOK 0 -#endif - -#ifndef portPRIVILEGE_BIT - #define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 ) -#endif - -#ifndef portYIELD_WITHIN_API - #define portYIELD_WITHIN_API portYIELD -#endif - -#ifndef pvPortMallocAligned - #define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( os_malloc( ( x ) ) ) : ( puxStackBuffer ) ) -#endif - -#ifndef vPortFreeAligned - #define vPortFreeAligned( pvBlockToFree ) os_free( pvBlockToFree ) -#endif - -#ifndef portSUPPRESS_TICKS_AND_SLEEP - #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) -#endif - -#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP - #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 -#endif - -#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 - #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 -#endif - -#ifndef configUSE_TICKLESS_IDLE - #define configUSE_TICKLESS_IDLE 0 -#endif - -#ifndef configPRE_SLEEP_PROCESSING - #define configPRE_SLEEP_PROCESSING( x ) -#endif - -#ifndef configPOST_SLEEP_PROCESSING - #define configPOST_SLEEP_PROCESSING( x ) -#endif - -#ifndef configUSE_QUEUE_SETS - #define configUSE_QUEUE_SETS 0 -#endif - -#ifndef portTASK_USES_FLOATING_POINT - #define portTASK_USES_FLOATING_POINT() -#endif - -#ifndef configUSE_TIME_SLICING - #define configUSE_TIME_SLICING 1 -#endif - -#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS - #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 -#endif - -#ifndef configUSE_NEWLIB_REENTRANT - #define configUSE_NEWLIB_REENTRANT 0 -#endif - -#ifndef configUSE_STATS_FORMATTING_FUNCTIONS - #define configUSE_STATS_FORMATTING_FUNCTIONS 0 -#endif - -#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID - #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() -#endif - -/* For backward compatability. */ -#define eTaskStateGet eTaskGetState - -#endif /* INC_FREERTOS_H */ - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +/* configUSE_PORT_OPTIMISED_TASK_SELECTION must be defined before portable.h +is included as it is used by the port layer. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#endif + +/* Definitions specific to the port being used. */ +#include "portable.h" + + +/* Defines the prototype to which the application task hook function must +conform. */ +typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * ); + + + + + +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configUSE_PREEMPTION + #error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK + #error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK + #error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_CO_ROUTINES + #error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskPrioritySet + #error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_uxTaskPriorityGet + #error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelete + #error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskSuspend + #error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelayUntil + #error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelay + #error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_16_BIT_TICKS + #error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_xTaskGetIdleTaskHandle + #define INCLUDE_xTaskGetIdleTaskHandle 0 +#endif + +#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle + #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#endif + +#ifndef INCLUDE_xQueueGetMutexHolder + #define INCLUDE_xQueueGetMutexHolder 0 +#endif + +#ifndef INCLUDE_xSemaphoreGetMutexHolder + #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder +#endif + +#ifndef INCLUDE_pcTaskGetTaskName + #define INCLUDE_pcTaskGetTaskName 0 +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef INCLUDE_eTaskGetState + #define INCLUDE_eTaskGetState 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API + #define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB + #define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef configASSERT + #define configASSERT( x ) + #define configASSERT_DEFINED 0 +#else + #define configASSERT_DEFINED 1 +#endif + +/* The timers module relies on xTaskGetSchedulerState(). */ +#if configUSE_TIMERS == 1 + + #ifndef configTIMER_TASK_PRIORITY + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. + #endif /* configTIMER_TASK_PRIORITY */ + + #ifndef configTIMER_QUEUE_LENGTH + #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. + #endif /* configTIMER_QUEUE_LENGTH */ + + #ifndef configTIMER_TASK_STACK_DEPTH + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. + #endif /* configTIMER_TASK_STACK_DEPTH */ + +#endif /* configUSE_TIMERS */ + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 0 +#endif + + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#endif + +#ifndef portCLEAN_UP_TCB + #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef portSETUP_TCB + #define portSETUP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 0U +#endif + +#if ( configQUEUE_REGISTRY_SIZE < 1 ) + #define vQueueAddToRegistry( xQueue, pcName ) + #define vQueueUnregisterQueue( xQueue ) +#endif + +#ifndef portPOINTER_SIZE_TYPE + #define portPOINTER_SIZE_TYPE unsigned long +#endif + +/* Remove any unused trace macros. */ +#ifndef traceSTART + /* Used to perform any necessary initialisation - for example, open a file + into which trace is to be written. */ + #define traceSTART() +#endif + +#ifndef traceEND + /* Use to close a trace, for example close a file into which trace has been + written. */ + #define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN + /* Called after a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the selected task. */ + #define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceINCREASE_TICK_COUNT + /* Called before stepping the tick count after waking from tickless idle + sleep. */ + #define traceINCREASE_TICK_COUNT( x ) +#endif + +#ifndef traceLOW_POWER_IDLE_BEGIN + /* Called immediately before entering tickless idle. */ + #define traceLOW_POWER_IDLE_BEGIN() +#endif + +#ifndef traceLOW_POWER_IDLE_END + /* Called when returning to the Idle task after a tickless idle. */ + #define traceLOW_POWER_IDLE_END() +#endif + +#ifndef traceTASK_SWITCHED_OUT + /* Called before a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the task being switched out. */ + #define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceTASK_PRIORITY_INHERIT + /* Called when a task attempts to take a mutex that is already held by a + lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task + that holds the mutex. uxInheritedPriority is the priority the mutex holder + will inherit (the priority of the task that is attempting to obtain the + muted. */ + #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) +#endif + +#ifndef traceTASK_PRIORITY_DISINHERIT + /* Called when a task releases a mutex, the holding of which had resulted in + the task inheriting the priority of a higher priority task. + pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the + mutex. uxOriginalPriority is the task's configured (base) priority. */ + #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND + /* Task is about to block because it cannot write to a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the write was attempted. pxCurrentTCB points to the TCB of the + task that attempted the write. */ + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceMOVED_TASK_TO_READY_STATE + #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED( ucQueueType ) +#endif + +#ifndef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE + #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE + #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED + #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE + #define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR + #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED + #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED() +#endif + +#ifndef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL + #define traceTASK_DELAY_UNTIL() +#endif + +#ifndef traceTASK_DELAY + #define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK + #define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef traceTIMER_CREATE + #define traceTIMER_CREATE( pxNewTimer ) +#endif + +#ifndef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() +#endif + +#ifndef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) +#endif + +#ifndef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( pxTimer ) +#endif + +#ifndef traceTIMER_COMMAND_RECEIVED + #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) +#endif + +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. + #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + + #ifndef portGET_RUN_TIME_COUNTER_VALUE + #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. + #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ + #endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT + #define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API + #define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef pvPortMallocAligned + #define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( os_malloc( ( x ) ) ) : ( puxStackBuffer ) ) +#endif + +#ifndef vPortFreeAligned + #define vPortFreeAligned( pvBlockToFree ) os_free( pvBlockToFree ) +#endif + +#ifndef portSUPPRESS_TICKS_AND_SLEEP + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) +#endif + +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 +#endif + +#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 + #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 +#endif + +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 +#endif + +#ifndef configPRE_SLEEP_PROCESSING + #define configPRE_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPOST_SLEEP_PROCESSING + #define configPOST_SLEEP_PROCESSING( x ) +#endif + +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif + +#ifndef portTASK_USES_FLOATING_POINT + #define portTASK_USES_FLOATING_POINT() +#endif + +#ifndef configUSE_TIME_SLICING + #define configUSE_TIME_SLICING 1 +#endif + +#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 +#endif + +#ifndef configUSE_NEWLIB_REENTRANT + #define configUSE_NEWLIB_REENTRANT 0 +#endif + +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#endif + +#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + +/* For backward compatability. */ +#define eTaskStateGet eTaskGetState + +#endif /* INC_FREERTOS_H */ + diff --git a/include/freertos/FreeRTOSConfig.h b/include/freertos/FreeRTOSConfig.h index 769b4370..520e1d48 100644 --- a/include/freertos/FreeRTOSConfig.h +++ b/include/freertos/FreeRTOSConfig.h @@ -1,144 +1,144 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ - -#define configUSE_PREEMPTION 1 -#define configUSE_IDLE_HOOK 1 -#define configUSE_TICK_HOOK 0 -#define configUSE_TICKLESS_IDLE 1 -#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 ) -#define configTICK_RATE_HZ ( ( portTickType ) 100 ) -#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 15 ) -#define configMINIMAL_STACK_SIZE ( ( unsigned short )176 ) -//#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) ) -#define configMAX_TASK_NAME_LEN ( 16 ) -#define configUSE_TRACE_FACILITY 0 -#define configUSE_STATS_FORMATTING_FUNCTIONS 0 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 - -#define INCLUDE_xTaskGetIdleTaskHandle 1 -#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 - -#define configCHECK_FOR_STACK_OVERFLOW 2 -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configUSE_TIMERS 1 - -#if configUSE_TIMERS -#define configTIMER_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) -#define configTIMER_QUEUE_LENGTH (10) -#define configTIMER_TASK_STACK_DEPTH ( ( unsigned short ) 512 ) -#endif - -/* Co-routine definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) - -/* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ - -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 0 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 - -/*set the #define for debug info*/ -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 1 - -/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 -(lowest) to 0 (1?) (highest). */ -#define configKERNEL_INTERRUPT_PRIORITY 255 -/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! -See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ -#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */ - - -/* This is the value being used as per the ST library which permits 16 -priority values, 0 to 15. This must correspond to the -configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest -NVIC value of 255. */ -#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 - -#endif /* FREERTOS_CONFIG_H */ - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 0 +#define configUSE_TICKLESS_IDLE 1 +#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 100 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 15 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short )176 ) +//#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 + +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 + +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_TIMERS 1 + +#if configUSE_TIMERS +#define configTIMER_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define configTIMER_QUEUE_LENGTH (10) +#define configTIMER_TASK_STACK_DEPTH ( ( unsigned short ) 512 ) +#endif + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +/*set the #define for debug info*/ +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 + +/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255 +(lowest) to 0 (1?) (highest). */ +#define configKERNEL_INTERRUPT_PRIORITY 255 +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */ + + +/* This is the value being used as per the ST library which permits 16 +priority values, 0 to 15. This must correspond to the +configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest +NVIC value of 255. */ +#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/include/freertos/StackMacros.h b/include/freertos/StackMacros.h index 7fa9503c..0a099df2 100644 --- a/include/freertos/StackMacros.h +++ b/include/freertos/StackMacros.h @@ -1,179 +1,179 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -#ifndef STACK_MACROS_H -#define STACK_MACROS_H - -/* - * Call the stack overflow hook function if the stack of the task being swapped - * out is currently overflowed, or looks like it might have overflowed in the - * past. - * - * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check - * the current stack state only - comparing the current top of stack value to - * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 - * will also cause the last few stack bytes to be checked to ensure the value - * to which the bytes were set when the task was created have not been - * overwritten. Note this second test does not guarantee that an overflowed - * stack will always be recognised. - */ - -/*-----------------------------------------------------------*/ - -#if( configCHECK_FOR_STACK_OVERFLOW == 0 ) - - /* FreeRTOSConfig.h is not set to check for stack overflows. */ - #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() - #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() - -#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */ -/*-----------------------------------------------------------*/ - -#if( configCHECK_FOR_STACK_OVERFLOW == 1 ) - - /* FreeRTOSConfig.h is only set to use the first method of - overflow checking. */ - #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() - -#endif -/*-----------------------------------------------------------*/ - -#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) ) - - /* Only the current stack state is to be checked. */ - #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ - { \ - /* Is the currently saved stack pointer within the stack limit? */ \ - if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ - { \ - vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ - } \ - } - -#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */ -/*-----------------------------------------------------------*/ - -#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) ) - - /* Only the current stack state is to be checked. */ - #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ - { \ - \ - /* Is the currently saved stack pointer within the stack limit? */ \ - if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ - { \ - vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ - } \ - } - -#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ -/*-----------------------------------------------------------*/ - -#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) - - #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ - { \ - static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ - tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ - tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ - tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ - tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ - \ - \ - /* Has the extremity of the task stack ever been written over? */ \ - if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ - { \ - vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ - } \ - } - -#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ -/*-----------------------------------------------------------*/ - -#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) - - #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ - { \ - char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \ - static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ - tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ - tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ - tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ - tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ - \ - \ - pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ - \ - /* Has the extremity of the task stack ever been written over? */ \ - if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ - { \ - vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ - } \ - } - -#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ -/*-----------------------------------------------------------*/ - -#endif /* STACK_MACROS_H */ - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( configCHECK_FOR_STACK_OVERFLOW == 0 ) + + /* FreeRTOSConfig.h is not set to check for stack overflows. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */ +/*-----------------------------------------------------------*/ + +#if( configCHECK_FOR_STACK_OVERFLOW == 1 ) + + /* FreeRTOSConfig.h is only set to use the first method of + overflow checking. */ + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() + +#endif +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ + { \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ + { \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ + { \ + static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ + { \ + char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \ + static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#endif /* STACK_MACROS_H */ + diff --git a/include/freertos/croutine.h b/include/freertos/croutine.h index fa082e65..94503e38 100644 --- a/include/freertos/croutine.h +++ b/include/freertos/croutine.h @@ -1,757 +1,757 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -#ifndef CO_ROUTINE_H -#define CO_ROUTINE_H - -#ifndef INC_FREERTOS_H - #error "include FreeRTOS.h must appear in source files before include croutine.h" -#endif - -#include "list.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Used to hide the implementation of the co-routine control block. The -control block structure however has to be included in the header due to -the macro implementation of the co-routine functionality. */ -typedef void * xCoRoutineHandle; - -/* Defines the prototype to which co-routine functions must conform. */ -typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE ); - -typedef struct corCoRoutineControlBlock -{ - crCOROUTINE_CODE pxCoRoutineFunction; - xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ - xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */ - unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ - unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ - unsigned short uxState; /*< Used internally by the co-routine implementation. */ -} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */ - -/** - * croutine. h - *
- portBASE_TYPE xCoRoutineCreate(
-                                 crCOROUTINE_CODE pxCoRoutineCode,
-                                 unsigned portBASE_TYPE uxPriority,
-                                 unsigned portBASE_TYPE uxIndex
-                               );
- * - * Create a new co-routine and add it to the list of co-routines that are - * ready to run. - * - * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine - * functions require special syntax - see the co-routine section of the WEB - * documentation for more information. - * - * @param uxPriority The priority with respect to other co-routines at which - * the co-routine will run. - * - * @param uxIndex Used to distinguish between different co-routines that - * execute the same function. See the example below and the co-routine section - * of the WEB documentation for further information. - * - * @return pdPASS if the co-routine was successfully created and added to a ready - * list, otherwise an error code defined with ProjDefs.h. - * - * Example usage: -
- // Co-routine to be created.
- void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
- {
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.
- // This may not be necessary for const variables.
- static const char cLedToFlash[ 2 ] = { 5, 6 };
- static const portTickType uxFlashRates[ 2 ] = { 200, 400 };
-
-     // Must start every co-routine with a call to crSTART();
-     crSTART( xHandle );
-
-     for( ;; )
-     {
-         // This co-routine just delays for a fixed period, then toggles
-         // an LED.  Two co-routines are created using this function, so
-         // the uxIndex parameter is used to tell the co-routine which
-         // LED to flash and how long to delay.  This assumes xQueue has
-         // already been created.
-         vParTestToggleLED( cLedToFlash[ uxIndex ] );
-         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
-     }
-
-     // Must end every co-routine with a call to crEND();
-     crEND();
- }
-
- // Function that creates two co-routines.
- void vOtherFunction( void )
- {
- unsigned char ucParameterToPass;
- xTaskHandle xHandle;
-		
-     // Create two co-routines at priority 0.  The first is given index 0
-     // so (from the code above) toggles LED 5 every 200 ticks.  The second
-     // is given index 1 so toggles LED 6 every 400 ticks.
-     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
-     {
-         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
-     }
- }
-   
- * \defgroup xCoRoutineCreate xCoRoutineCreate - * \ingroup Tasks - */ -signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ); - - -/** - * croutine. h - *
- void vCoRoutineSchedule( void );
- * - * Run a co-routine. - * - * vCoRoutineSchedule() executes the highest priority co-routine that is able - * to run. The co-routine will execute until it either blocks, yields or is - * preempted by a task. Co-routines execute cooperatively so one - * co-routine cannot be preempted by another, but can be preempted by a task. - * - * If an application comprises of both tasks and co-routines then - * vCoRoutineSchedule should be called from the idle task (in an idle task - * hook). - * - * Example usage: -
- // This idle task hook will schedule a co-routine each time it is called.
- // The rest of the idle task will execute between co-routine calls.
- void vApplicationIdleHook( void )
- {
-	vCoRoutineSchedule();
- }
-
- // Alternatively, if you do not require any other part of the idle task to
- // execute, the idle task hook can call vCoRoutineScheduler() within an
- // infinite loop.
- void vApplicationIdleHook( void )
- {
-    for( ;; )
-    {
-        vCoRoutineSchedule();
-    }
- }
- 
- * \defgroup vCoRoutineSchedule vCoRoutineSchedule - * \ingroup Tasks - */ -void vCoRoutineSchedule( void ); - -/** - * croutine. h - *
- crSTART( xCoRoutineHandle xHandle );
- * - * This macro MUST always be called at the start of a co-routine function. - * - * Example usage: -
- // Co-routine to be created.
- void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
- {
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.
- static long ulAVariable;
-
-     // Must start every co-routine with a call to crSTART();
-     crSTART( xHandle );
-
-     for( ;; )
-     {
-          // Co-routine functionality goes here.
-     }
-
-     // Must end every co-routine with a call to crEND();
-     crEND();
- }
- * \defgroup crSTART crSTART - * \ingroup Tasks - */ -#define crSTART( pxCRCB ) switch( ( ( corCRCB * )( pxCRCB ) )->uxState ) { case 0: - -/** - * croutine. h - *
- crEND();
- * - * This macro MUST always be called at the end of a co-routine function. - * - * Example usage: -
- // Co-routine to be created.
- void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
- {
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.
- static long ulAVariable;
-
-     // Must start every co-routine with a call to crSTART();
-     crSTART( xHandle );
-
-     for( ;; )
-     {
-          // Co-routine functionality goes here.
-     }
-
-     // Must end every co-routine with a call to crEND();
-     crEND();
- }
- * \defgroup crSTART crSTART - * \ingroup Tasks - */ -#define crEND() } - -/* - * These macros are intended for internal use by the co-routine implementation - * only. The macros should not be used directly by application writers. - */ -#define crSET_STATE0( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): -#define crSET_STATE1( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): - -/** - * croutine. h - *
- crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );
- * - * Delay a co-routine for a fixed period of time. - * - * crDELAY can only be called from the co-routine function itself - not - * from within a function called by the co-routine function. This is because - * co-routines do not maintain their own stack. - * - * @param xHandle The handle of the co-routine to delay. This is the xHandle - * parameter of the co-routine function. - * - * @param xTickToDelay The number of ticks that the co-routine should delay - * for. The actual amount of time this equates to is defined by - * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS - * can be used to convert ticks to milliseconds. - * - * Example usage: -
- // Co-routine to be created.
- void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
- {
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.
- // This may not be necessary for const variables.
- // We are to delay for 200ms.
- static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
-
-     // Must start every co-routine with a call to crSTART();
-     crSTART( xHandle );
-
-     for( ;; )
-     {
-        // Delay for 200ms.
-        crDELAY( xHandle, xDelayTime );
-
-        // Do something here.
-     }
-
-     // Must end every co-routine with a call to crEND();
-     crEND();
- }
- * \defgroup crDELAY crDELAY - * \ingroup Tasks - */ -#define crDELAY( xHandle, xTicksToDelay ) \ - if( ( xTicksToDelay ) > 0 ) \ - { \ - vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ - } \ - crSET_STATE0( ( xHandle ) ); - -/** - *
- crQUEUE_SEND(
-                  xCoRoutineHandle xHandle,
-                  xQueueHandle pxQueue,
-                  void *pvItemToQueue,
-                  portTickType xTicksToWait,
-                  portBASE_TYPE *pxResult
-             )
- * - * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine - * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. - * - * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas - * xQueueSend() and xQueueReceive() can only be used from tasks. - * - * crQUEUE_SEND can only be called from the co-routine function itself - not - * from within a function called by the co-routine function. This is because - * co-routines do not maintain their own stack. - * - * See the co-routine section of the WEB documentation for information on - * passing data between tasks and co-routines and between ISR's and - * co-routines. - * - * @param xHandle The handle of the calling co-routine. This is the xHandle - * parameter of the co-routine function. - * - * @param pxQueue The handle of the queue on which the data will be posted. - * The handle is obtained as the return value when the queue is created using - * the xQueueCreate() API function. - * - * @param pvItemToQueue A pointer to the data being posted onto the queue. - * The number of bytes of each queued item is specified when the queue is - * created. This number of bytes is copied from pvItemToQueue into the queue - * itself. - * - * @param xTickToDelay The number of ticks that the co-routine should block - * to wait for space to become available on the queue, should space not be - * available immediately. The actual amount of time this equates to is defined - * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant - * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example - * below). - * - * @param pxResult The variable pointed to by pxResult will be set to pdPASS if - * data was successfully posted onto the queue, otherwise it will be set to an - * error defined within ProjDefs.h. - * - * Example usage: -
- // Co-routine function that blocks for a fixed period then posts a number onto
- // a queue.
- static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
- {
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.
- static portBASE_TYPE xNumberToPost = 0;
- static portBASE_TYPE xResult;
-
-    // Co-routines must begin with a call to crSTART().
-    crSTART( xHandle );
-
-    for( ;; )
-    {
-        // This assumes the queue has already been created.
-        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
-
-        if( xResult != pdPASS )
-        {
-            // The message was not posted!
-        }
-
-        // Increment the number to be posted onto the queue.
-        xNumberToPost++;
-
-        // Delay for 100 ticks.
-        crDELAY( xHandle, 100 );
-    }
-
-    // Co-routines must end with a call to crEND().
-    crEND();
- }
- * \defgroup crQUEUE_SEND crQUEUE_SEND - * \ingroup Tasks - */ -#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ -{ \ - *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ - if( *( pxResult ) == errQUEUE_BLOCKED ) \ - { \ - crSET_STATE0( ( xHandle ) ); \ - *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ - } \ - if( *pxResult == errQUEUE_YIELD ) \ - { \ - crSET_STATE1( ( xHandle ) ); \ - *pxResult = pdPASS; \ - } \ -} - -/** - * croutine. h - *
-  crQUEUE_RECEIVE(
-                     xCoRoutineHandle xHandle,
-                     xQueueHandle pxQueue,
-                     void *pvBuffer,
-                     portTickType xTicksToWait,
-                     portBASE_TYPE *pxResult
-                 )
- * - * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine - * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. - * - * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas - * xQueueSend() and xQueueReceive() can only be used from tasks. - * - * crQUEUE_RECEIVE can only be called from the co-routine function itself - not - * from within a function called by the co-routine function. This is because - * co-routines do not maintain their own stack. - * - * See the co-routine section of the WEB documentation for information on - * passing data between tasks and co-routines and between ISR's and - * co-routines. - * - * @param xHandle The handle of the calling co-routine. This is the xHandle - * parameter of the co-routine function. - * - * @param pxQueue The handle of the queue from which the data will be received. - * The handle is obtained as the return value when the queue is created using - * the xQueueCreate() API function. - * - * @param pvBuffer The buffer into which the received item is to be copied. - * The number of bytes of each queued item is specified when the queue is - * created. This number of bytes is copied into pvBuffer. - * - * @param xTickToDelay The number of ticks that the co-routine should block - * to wait for data to become available from the queue, should data not be - * available immediately. The actual amount of time this equates to is defined - * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant - * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the - * crQUEUE_SEND example). - * - * @param pxResult The variable pointed to by pxResult will be set to pdPASS if - * data was successfully retrieved from the queue, otherwise it will be set to - * an error code as defined within ProjDefs.h. - * - * Example usage: -
- // A co-routine receives the number of an LED to flash from a queue.  It
- // blocks on the queue until the number is received.
- static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
- {
- // Variables in co-routines must be declared static if they must maintain value across a blocking call.
- static portBASE_TYPE xResult;
- static unsigned portBASE_TYPE uxLEDToFlash;
-
-    // All co-routines must start with a call to crSTART().
-    crSTART( xHandle );
-
-    for( ;; )
-    {
-        // Wait for data to become available on the queue.
-        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
-
-        if( xResult == pdPASS )
-        {
-            // We received the LED to flash - flash it!
-            vParTestToggleLED( uxLEDToFlash );
-        }
-    }
-
-    crEND();
- }
- * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE - * \ingroup Tasks - */ -#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ -{ \ - *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ - if( *( pxResult ) == errQUEUE_BLOCKED ) \ - { \ - crSET_STATE0( ( xHandle ) ); \ - *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ - } \ - if( *( pxResult ) == errQUEUE_YIELD ) \ - { \ - crSET_STATE1( ( xHandle ) ); \ - *( pxResult ) = pdPASS; \ - } \ -} - -/** - * croutine. h - *
-  crQUEUE_SEND_FROM_ISR(
-                            xQueueHandle pxQueue,
-                            void *pvItemToQueue,
-                            portBASE_TYPE xCoRoutinePreviouslyWoken
-                       )
- * - * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the - * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() - * functions used by tasks. - * - * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to - * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and - * xQueueReceiveFromISR() can only be used to pass data between a task and and - * ISR. - * - * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue - * that is being used from within a co-routine. - * - * See the co-routine section of the WEB documentation for information on - * passing data between tasks and co-routines and between ISR's and - * co-routines. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto - * the same queue multiple times from a single interrupt. The first call - * should always pass in pdFALSE. Subsequent calls should pass in - * the value returned from the previous call. - * - * @return pdTRUE if a co-routine was woken by posting onto the queue. This is - * used by the ISR to determine if a context switch may be required following - * the ISR. - * - * Example usage: -
- // A co-routine that blocks on a queue waiting for characters to be received.
- static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
- {
- char cRxedChar;
- portBASE_TYPE xResult;
-
-     // All co-routines must start with a call to crSTART().
-     crSTART( xHandle );
-
-     for( ;; )
-     {
-         // Wait for data to become available on the queue.  This assumes the
-         // queue xCommsRxQueue has already been created!
-         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
-
-         // Was a character received?
-         if( xResult == pdPASS )
-         {
-             // Process the character here.
-         }
-     }
-
-     // All co-routines must end with a call to crEND().
-     crEND();
- }
-
- // An ISR that uses a queue to send characters received on a serial port to
- // a co-routine.
- void vUART_ISR( void )
- {
- char cRxedChar;
- portBASE_TYPE xCRWokenByPost = pdFALSE;
-
-     // We loop around reading characters until there are none left in the UART.
-     while( UART_RX_REG_NOT_EMPTY() )
-     {
-         // Obtain the character from the UART.
-         cRxedChar = UART_RX_REG;
-
-         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
-         // the first time around the loop.  If the post causes a co-routine
-         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
-         // In this manner we can ensure that if more than one co-routine is
-         // blocked on the queue only one is woken by this ISR no matter how
-         // many characters are posted to the queue.
-         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
-     }
- }
- * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR - * \ingroup Tasks - */ -#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) - - -/** - * croutine. h - *
-  crQUEUE_SEND_FROM_ISR(
-                            xQueueHandle pxQueue,
-                            void *pvBuffer,
-                            portBASE_TYPE * pxCoRoutineWoken
-                       )
- * - * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the - * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() - * functions used by tasks. - * - * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to - * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and - * xQueueReceiveFromISR() can only be used to pass data between a task and and - * ISR. - * - * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data - * from a queue that is being used from within a co-routine (a co-routine - * posted to the queue). - * - * See the co-routine section of the WEB documentation for information on - * passing data between tasks and co-routines and between ISR's and - * co-routines. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvBuffer A pointer to a buffer into which the received item will be - * placed. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from the queue into - * pvBuffer. - * - * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become - * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a - * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise - * *pxCoRoutineWoken will remain unchanged. - * - * @return pdTRUE an item was successfully received from the queue, otherwise - * pdFALSE. - * - * Example usage: -
- // A co-routine that posts a character to a queue then blocks for a fixed
- // period.  The character is incremented each time.
- static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
- {
- // cChar holds its value while this co-routine is blocked and must therefore
- // be declared static.
- static char cCharToTx = 'a';
- portBASE_TYPE xResult;
-
-     // All co-routines must start with a call to crSTART().
-     crSTART( xHandle );
-
-     for( ;; )
-     {
-         // Send the next character to the queue.
-         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
-
-         if( xResult == pdPASS )
-         {
-             // The character was successfully posted to the queue.
-         }
-		 else
-		 {
-			// Could not post the character to the queue.
-		 }
-
-         // Enable the UART Tx interrupt to cause an interrupt in this
-		 // hypothetical UART.  The interrupt will obtain the character
-		 // from the queue and send it.
-		 ENABLE_RX_INTERRUPT();
-
-		 // Increment to the next character then block for a fixed period.
-		 // cCharToTx will maintain its value across the delay as it is
-		 // declared static.
-		 cCharToTx++;
-		 if( cCharToTx > 'x' )
-		 {
-			cCharToTx = 'a';
-		 }
-		 crDELAY( 100 );
-     }
-
-     // All co-routines must end with a call to crEND().
-     crEND();
- }
-
- // An ISR that uses a queue to receive characters to send on a UART.
- void vUART_ISR( void )
- {
- char cCharToTx;
- portBASE_TYPE xCRWokenByPost = pdFALSE;
-
-     while( UART_TX_REG_EMPTY() )
-     {
-         // Are there any characters in the queue waiting to be sent?
-		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
-		 // is woken by the post - ensuring that only a single co-routine is
-		 // woken no matter how many times we go around this loop.
-         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
-		 {
-			 SEND_CHARACTER( cCharToTx );
-		 }
-     }
- }
- * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR - * \ingroup Tasks - */ -#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) - -/* - * This function is intended for internal use by the co-routine macros only. - * The macro nature of the co-routine implementation requires that the - * prototype appears here. The function should not be used by application - * writers. - * - * Removes the current co-routine from its ready list and places it in the - * appropriate delayed list. - */ -void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ); - -/* - * This function is intended for internal use by the queue implementation only. - * The function should not be used by application writers. - * - * Removes the highest priority co-routine from the event list and places it in - * the pending ready list. - */ -signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ); - -#ifdef __cplusplus -} -#endif - -#endif /* CO_ROUTINE_H */ +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to hide the implementation of the co-routine control block. The +control block structure however has to be included in the header due to +the macro implementation of the co-routine functionality. */ +typedef void * xCoRoutineHandle; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ + xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */ + unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ + unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + unsigned short uxState; /*< Used internally by the co-routine implementation. */ +} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */ + +/** + * croutine. h + *
+ portBASE_TYPE xCoRoutineCreate(
+                                 crCOROUTINE_CODE pxCoRoutineCode,
+                                 unsigned portBASE_TYPE uxPriority,
+                                 unsigned portBASE_TYPE uxIndex
+                               );
+ * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: +
+ // Co-routine to be created.
+ void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const portTickType uxFlashRates[ 2 ] = { 200, 400 };
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // This co-routine just delays for a fixed period, then toggles
+         // an LED.  Two co-routines are created using this function, so
+         // the uxIndex parameter is used to tell the co-routine which
+         // LED to flash and how long to delay.  This assumes xQueue has
+         // already been created.
+         vParTestToggleLED( cLedToFlash[ uxIndex ] );
+         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+		
+     // Create two co-routines at priority 0.  The first is given index 0
+     // so (from the code above) toggles LED 5 every 200 ticks.  The second
+     // is given index 1 so toggles LED 6 every 400 ticks.
+     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+     {
+         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+     }
+ }
+   
+ * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ); + + +/** + * croutine. h + *
+ void vCoRoutineSchedule( void );
+ * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: +
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+	vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+    for( ;; )
+    {
+        vCoRoutineSchedule();
+    }
+ }
+ 
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + *
+ crSTART( xCoRoutineHandle xHandle );
+ * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static long ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) switch( ( ( corCRCB * )( pxCRCB ) )->uxState ) { case 0: + +/** + * croutine. h + *
+ crEND();
+ * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static long ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): +#define crSET_STATE1( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): + +/** + * croutine. h + *
+ crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );
+ * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+        // Delay for 200ms.
+        crDELAY( xHandle, xDelayTime );
+
+        // Do something here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + if( ( xTicksToDelay ) > 0 ) \ + { \ + vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ + } \ + crSET_STATE0( ( xHandle ) ); + +/** + *
+ crQUEUE_SEND(
+                  xCoRoutineHandle xHandle,
+                  xQueueHandle pxQueue,
+                  void *pvItemToQueue,
+                  portTickType xTicksToWait,
+                  portBASE_TYPE *pxResult
+             )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_RATE_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: +
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xNumberToPost = 0;
+ static portBASE_TYPE xResult;
+
+    // Co-routines must begin with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // This assumes the queue has already been created.
+        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+        if( xResult != pdPASS )
+        {
+            // The message was not posted!
+        }
+
+        // Increment the number to be posted onto the queue.
+        xNumberToPost++;
+
+        // Delay for 100 ticks.
+        crDELAY( xHandle, 100 );
+    }
+
+    // Co-routines must end with a call to crEND().
+    crEND();
+ }
+ * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_RECEIVE(
+                     xCoRoutineHandle xHandle,
+                     xQueueHandle pxQueue,
+                     void *pvBuffer,
+                     portTickType xTicksToWait,
+                     portBASE_TYPE *pxResult
+                 )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_RATE_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: +
+ // A co-routine receives the number of an LED to flash from a queue.  It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static portBASE_TYPE xResult;
+ static unsigned portBASE_TYPE uxLEDToFlash;
+
+    // All co-routines must start with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // Wait for data to become available on the queue.
+        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+        if( xResult == pdPASS )
+        {
+            // We received the LED to flash - flash it!
+            vParTestToggleLED( uxLEDToFlash );
+        }
+    }
+
+    crEND();
+ }
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ + } \ + if( *( pxResult ) == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *( pxResult ) = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            xQueueHandle pxQueue,
+                            void *pvItemToQueue,
+                            portBASE_TYPE xCoRoutinePreviouslyWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: +
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ char cRxedChar;
+ portBASE_TYPE xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Wait for data to become available on the queue.  This assumes the
+         // queue xCommsRxQueue has already been created!
+         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+         // Was a character received?
+         if( xResult == pdPASS )
+         {
+             // Process the character here.
+         }
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+     // We loop around reading characters until there are none left in the UART.
+     while( UART_RX_REG_NOT_EMPTY() )
+     {
+         // Obtain the character from the UART.
+         cRxedChar = UART_RX_REG;
+
+         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
+         // the first time around the loop.  If the post causes a co-routine
+         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+         // In this manner we can ensure that if more than one co-routine is
+         // blocked on the queue only one is woken by this ISR no matter how
+         // many characters are posted to the queue.
+         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+     }
+ }
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) + + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            xQueueHandle pxQueue,
+                            void *pvBuffer,
+                            portBASE_TYPE * pxCoRoutineWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: +
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period.  The character is incremented each time.
+ static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ portBASE_TYPE xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Send the next character to the queue.
+         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+         if( xResult == pdPASS )
+         {
+             // The character was successfully posted to the queue.
+         }
+		 else
+		 {
+			// Could not post the character to the queue.
+		 }
+
+         // Enable the UART Tx interrupt to cause an interrupt in this
+		 // hypothetical UART.  The interrupt will obtain the character
+		 // from the queue and send it.
+		 ENABLE_RX_INTERRUPT();
+
+		 // Increment to the next character then block for a fixed period.
+		 // cCharToTx will maintain its value across the delay as it is
+		 // declared static.
+		 cCharToTx++;
+		 if( cCharToTx > 'x' )
+		 {
+			cCharToTx = 'a';
+		 }
+		 crDELAY( 100 );
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ portBASE_TYPE xCRWokenByPost = pdFALSE;
+
+     while( UART_TX_REG_EMPTY() )
+     {
+         // Are there any characters in the queue waiting to be sent?
+		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+		 // is woken by the post - ensuring that only a single co-routine is
+		 // woken no matter how many times we go around this loop.
+         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+		 {
+			 SEND_CHARACTER( cCharToTx );
+		 }
+     }
+ }
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ); + +#ifdef __cplusplus +} +#endif + +#endif /* CO_ROUTINE_H */ diff --git a/include/freertos/list.h b/include/freertos/list.h index 7511be3b..a8bafb06 100644 --- a/include/freertos/list.h +++ b/include/freertos/list.h @@ -1,378 +1,378 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -/* - * This is the list implementation used by the scheduler. While it is tailored - * heavily for the schedulers needs, it is also available for use by - * application code. - * - * xLists can only store pointers to xListItems. Each xListItem contains a - * numeric value (xItemValue). Most of the time the lists are sorted in - * descending item value order. - * - * Lists are created already containing one list item. The value of this - * item is the maximum possible that can be stored, it is therefore always at - * the end of the list and acts as a marker. The list member pxHead always - * points to this marker - even though it is at the tail of the list. This - * is because the tail contains a wrap back pointer to the true head of - * the list. - * - * In addition to it's value, each list item contains a pointer to the next - * item in the list (pxNext), a pointer to the list it is in (pxContainer) - * and a pointer to back to the object that contains it. These later two - * pointers are included for efficiency of list manipulation. There is - * effectively a two way link between the object containing the list item and - * the list item itself. - * - * - * \page ListIntroduction List Implementation - * \ingroup FreeRTOSIntro - */ - - -#ifndef LIST_H -#define LIST_H - -/* - * The list structure members are modified from within interrupts, and therefore - * by rights should be declared volatile. However, they are only modified in a - * functionally atomic way (within critical sections of with the scheduler - * suspended) and are either passed by reference into a function or indexed via - * a volatile variable. Therefore, in all use cases tested so far, the volatile - * qualifier can be omitted in order to provide a moderate performance - * improvement without adversely affecting functional behaviour. The assembly - * instructions generated by the IAR, ARM and GCC compilers when the respective - * compiler's options were set for maximum optimisation has been inspected and - * deemed to be as intended. That said, as compiler technology advances, and - * especially if aggressive cross module optimisation is used (a use case that - * has not been exercised to any great extend) then it is feasible that the - * volatile qualifier will be needed for correct optimisation. It is expected - * that a compiler removing essential code because, without the volatile - * qualifier on the list structure members and with aggressive cross module - * optimisation, the compiler deemed the code unnecessary will result in - * complete and obvious failure of the scheduler. If this is ever experienced - * then the volatile qualifier can be inserted in the relevant places within the - * list structures by simply defining configLIST_VOLATILE to volatile in - * FreeRTOSConfig.h (as per the example at the bottom of this comment block). - * If configLIST_VOLATILE is not defined then the preprocessor directives below - * will simply #define configLIST_VOLATILE away completely. - * - * To use volatile list structure members then add the following line to - * FreeRTOSConfig.h (without the quotes): - * "#define configLIST_VOLATILE volatile" - */ -#ifndef configLIST_VOLATILE - #define configLIST_VOLATILE -#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ - -#ifdef __cplusplus -extern "C" { -#endif -/* - * Definition of the only type of object that a list can contain. - */ -struct xLIST_ITEM -{ - configLIST_VOLATILE portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ - struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next xListItem in the list. */ - struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;/*< Pointer to the previous xListItem in the list. */ - void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ - void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */ -}; -typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */ - -struct xMINI_LIST_ITEM -{ - configLIST_VOLATILE portTickType xItemValue; - struct xLIST_ITEM * configLIST_VOLATILE pxNext; - struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; -}; -typedef struct xMINI_LIST_ITEM xMiniListItem; - -/* - * Definition of the type of queue used by the scheduler. - */ -typedef struct xLIST -{ - configLIST_VOLATILE unsigned portBASE_TYPE uxNumberOfItems; - xListItem * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */ - xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ -} xList; - -/* - * Access macro to set the owner of a list item. The owner of a list item - * is the object (usually a TCB) that contains the list item. - * - * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER - * \ingroup LinkedList - */ -#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) - -/* - * Access macro to get the owner of a list item. The owner of a list item - * is the object (usually a TCB) that contains the list item. - * - * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER - * \ingroup LinkedList - */ -#define listGET_LIST_ITEM_OWNER( pxListItem ) ( pxListItem )->pvOwner - -/* - * Access macro to set the value of the list item. In most cases the value is - * used to sort the list in descending order. - * - * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE - * \ingroup LinkedList - */ -#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) - -/* - * Access macro to retrieve the value of the list item. The value can - * represent anything - for example a the priority of a task, or the time at - * which a task should be unblocked. - * - * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE - * \ingroup LinkedList - */ -#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) - -/* - * Access macro the retrieve the value of the list item at the head of a given - * list. - * - * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE - * \ingroup LinkedList - */ -#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->xItemValue ) - -/* - * Access macro to determine if a list contains any items. The macro will - * only have the value true if the list is empty. - * - * \page listLIST_IS_EMPTY listLIST_IS_EMPTY - * \ingroup LinkedList - */ -#define listLIST_IS_EMPTY( pxList ) ( ( portBASE_TYPE ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 ) ) - -/* - * Access macro to return the number of items in the list. - */ -#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) - -/* - * Access function to obtain the owner of the next entry in a list. - * - * The list member pxIndex is used to walk through a list. Calling - * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list - * and returns that entries pxOwner parameter. Using multiple calls to this - * function it is therefore possible to move through every item contained in - * a list. - * - * The pxOwner parameter of a list item is a pointer to the object that owns - * the list item. In the scheduler this is normally a task control block. - * The pxOwner parameter effectively creates a two way link between the list - * item and its owner. - * - * @param pxList The list from which the next item owner is to be returned. - * - * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY - * \ingroup LinkedList - */ -#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ -{ \ -xList * const pxConstList = ( pxList ); \ - /* Increment the index to the next item and return the item, ensuring */ \ - /* we don't return the marker used at the end of the list. */ \ - ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ - if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ - { \ - ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ - } \ - ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ -} - - -/* - * Access function to obtain the owner of the first entry in a list. Lists - * are normally sorted in ascending item value order. - * - * This function returns the pxOwner member of the first item in the list. - * The pxOwner parameter of a list item is a pointer to the object that owns - * the list item. In the scheduler this is normally a task control block. - * The pxOwner parameter effectively creates a two way link between the list - * item and its owner. - * - * @param pxList The list from which the owner of the head item is to be - * returned. - * - * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY - * \ingroup LinkedList - */ -#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) - -/* - * Check to see if a list item is within a list. The list item maintains a - * "container" pointer that points to the list it is in. All this macro does - * is check to see if the container and the list match. - * - * @param pxList The list we want to know if the list item is within. - * @param pxListItem The list item we want to know if is in the list. - * @return pdTRUE is the list item is in the list, otherwise pdFALSE. - * pointer against - */ -#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( portBASE_TYPE ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) ) - -/* - * Return the list a list item is contained within (referenced from). - * - * @param pxListItem The list item being queried. - * @return A pointer to the xList object that references the pxListItem - */ -#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer ) - -/* - * This provides a crude means of knowing if a list has been initialised, as - * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() - * function. - */ -#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) - -/* - * Must be called before a list is used! This initialises all the members - * of the list structure and inserts the xListEnd item into the list as a - * marker to the back of the list. - * - * @param pxList Pointer to the list being initialised. - * - * \page vListInitialise vListInitialise - * \ingroup LinkedList - */ -void vListInitialise( xList * const pxList ); - -/* - * Must be called before a list item is used. This sets the list container to - * null so the item does not think that it is already contained in a list. - * - * @param pxItem Pointer to the list item being initialised. - * - * \page vListInitialiseItem vListInitialiseItem - * \ingroup LinkedList - */ -void vListInitialiseItem( xListItem * const pxItem ); - -/* - * Insert a list item into a list. The item will be inserted into the list in - * a position determined by its item value (descending item value order). - * - * @param pxList The list into which the item is to be inserted. - * - * @param pxNewListItem The item to that is to be placed in the list. - * - * \page vListInsert vListInsert - * \ingroup LinkedList - */ -void vListInsert( xList * const pxList, xListItem * const pxNewListItem ); - -/* - * Insert a list item into a list. The item will be inserted in a position - * such that it will be the last item within the list returned by multiple - * calls to listGET_OWNER_OF_NEXT_ENTRY. - * - * The list member pvIndex is used to walk through a list. Calling - * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list. - * Placing an item in a list using vListInsertEnd effectively places the item - * in the list position pointed to by pvIndex. This means that every other - * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before - * the pvIndex parameter again points to the item being inserted. - * - * @param pxList The list into which the item is to be inserted. - * - * @param pxNewListItem The list item to be inserted into the list. - * - * \page vListInsertEnd vListInsertEnd - * \ingroup LinkedList - */ -void vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem ); - -/* - * Remove an item from a list. The list item has a pointer to the list that - * it is in, so only the list item need be passed into the function. - * - * @param uxListRemove The item to be removed. The item will remove itself from - * the list pointed to by it's pxContainer parameter. - * - * @return The number of items that remain in the list after the list item has - * been removed. - * - * \page uxListRemove uxListRemove - * \ingroup LinkedList - */ -unsigned portBASE_TYPE uxListRemove( xListItem * const pxItemToRemove ); - -#ifdef __cplusplus -} -#endif - -#endif - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * xLists can only store pointers to xListItems. Each xListItem contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * descending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + + +#ifndef LIST_H +#define LIST_H + +/* + * The list structure members are modified from within interrupts, and therefore + * by rights should be declared volatile. However, they are only modified in a + * functionally atomic way (within critical sections of with the scheduler + * suspended) and are either passed by reference into a function or indexed via + * a volatile variable. Therefore, in all use cases tested so far, the volatile + * qualifier can be omitted in order to provide a moderate performance + * improvement without adversely affecting functional behaviour. The assembly + * instructions generated by the IAR, ARM and GCC compilers when the respective + * compiler's options were set for maximum optimisation has been inspected and + * deemed to be as intended. That said, as compiler technology advances, and + * especially if aggressive cross module optimisation is used (a use case that + * has not been exercised to any great extend) then it is feasible that the + * volatile qualifier will be needed for correct optimisation. It is expected + * that a compiler removing essential code because, without the volatile + * qualifier on the list structure members and with aggressive cross module + * optimisation, the compiler deemed the code unnecessary will result in + * complete and obvious failure of the scheduler. If this is ever experienced + * then the volatile qualifier can be inserted in the relevant places within the + * list structures by simply defining configLIST_VOLATILE to volatile in + * FreeRTOSConfig.h (as per the example at the bottom of this comment block). + * If configLIST_VOLATILE is not defined then the preprocessor directives below + * will simply #define configLIST_VOLATILE away completely. + * + * To use volatile list structure members then add the following line to + * FreeRTOSConfig.h (without the quotes): + * "#define configLIST_VOLATILE volatile" + */ +#ifndef configLIST_VOLATILE + #define configLIST_VOLATILE +#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST_ITEM +{ + configLIST_VOLATILE portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ + struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next xListItem in the list. */ + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;/*< Pointer to the previous xListItem in the list. */ + void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */ +}; +typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */ + +struct xMINI_LIST_ITEM +{ + configLIST_VOLATILE portTickType xItemValue; + struct xLIST_ITEM * configLIST_VOLATILE pxNext; + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; +}; +typedef struct xMINI_LIST_ITEM xMiniListItem; + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + configLIST_VOLATILE unsigned portBASE_TYPE uxNumberOfItems; + xListItem * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */ + xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ +} xList; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) + +/* + * Access macro to get the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_OWNER( pxListItem ) ( pxListItem )->pvOwner + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in descending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) + +/* + * Access macro to retrieve the value of the list item. The value can + * represent anything - for example a the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro the retrieve the value of the list item at the head of a given + * list. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->xItemValue ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( portBASE_TYPE ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 ) ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entries pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ +{ \ +xList * const pxConstList = ( pxList ); \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + } \ + ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ +} + + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE is the list item is in the list, otherwise pdFALSE. + * pointer against + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( portBASE_TYPE ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) ) + +/* + * Return the list a list item is contained within (referenced from). + * + * @param pxListItem The list item being queried. + * @return A pointer to the xList object that references the pxListItem + */ +#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer ) + +/* + * This provides a crude means of knowing if a list has been initialised, as + * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() + * function. + */ +#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise( xList * const pxList ); + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem( xListItem * const pxItem ); + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (descending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item to that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert( xList * const pxList, xListItem * const pxNewListItem ); + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pvIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pvIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pvIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem ); + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page uxListRemove uxListRemove + * \ingroup LinkedList + */ +unsigned portBASE_TYPE uxListRemove( xListItem * const pxItemToRemove ); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/freertos/mpu_wrappers.h b/include/freertos/mpu_wrappers.h index e3e22461..66350699 100644 --- a/include/freertos/mpu_wrappers.h +++ b/include/freertos/mpu_wrappers.h @@ -1,152 +1,152 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -#ifndef MPU_WRAPPERS_H -#define MPU_WRAPPERS_H - -/* This file redefines API functions to be called through a wrapper macro, but -only for ports that are using the MPU. */ -#ifdef portUSING_MPU_WRAPPERS - - /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is - included from queue.c or task.c to prevent it from having an effect within - those files. */ - #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE - - #define xTaskGenericCreate MPU_xTaskGenericCreate - #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions - #define vTaskDelete MPU_vTaskDelete - #define vTaskDelayUntil MPU_vTaskDelayUntil - #define vTaskDelay MPU_vTaskDelay - #define uxTaskPriorityGet MPU_uxTaskPriorityGet - #define vTaskPrioritySet MPU_vTaskPrioritySet - #define eTaskGetState MPU_eTaskGetState - #define vTaskSuspend MPU_vTaskSuspend - #define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended - #define vTaskResume MPU_vTaskResume - #define vTaskSuspendAll MPU_vTaskSuspendAll - #define xTaskResumeAll MPU_xTaskResumeAll - #define xTaskGetTickCount MPU_xTaskGetTickCount - #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks - #define vTaskList MPU_vTaskList - #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats - #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag - #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag - #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook - #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark - #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle - #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState - #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle - #define uxTaskGetSystemState MPU_uxTaskGetSystemState - - #define xQueueGenericCreate MPU_xQueueGenericCreate - #define xQueueCreateMutex MPU_xQueueCreateMutex - #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive - #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive - #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore - #define xQueueGenericSend MPU_xQueueGenericSend - #define xQueueAltGenericSend MPU_xQueueAltGenericSend - #define xQueueAltGenericReceive MPU_xQueueAltGenericReceive - #define xQueueGenericReceive MPU_xQueueGenericReceive - #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting - #define vQueueDelete MPU_vQueueDelete - #define xQueueGenericReset MPU_xQueueGenericReset - #define xQueueCreateSet MPU_xQueueCreateSet - #define xQueueSelectFromSet MPU_xQueueSelectFromSet - #define xQueueAddToSet MPU_xQueueAddToSet - #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet - #define xQueuePeekFromISR MPU_xQueuePeekFromISR - - #define pvPortMalloc MPU_pvPortMalloc - #define vPortFree MPU_vPortFree - #define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize - #define vPortInitialiseBlocks MPU_vPortInitialiseBlocks - - #if configQUEUE_REGISTRY_SIZE > 0 - #define vQueueAddToRegistry MPU_vQueueAddToRegistry - #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue - #endif - - /* Remove the privileged function macro. */ - #define PRIVILEGED_FUNCTION - - #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ - - /* Ensure API functions go in the privileged execution section. */ - #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) - #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) - - #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ - -#else /* portUSING_MPU_WRAPPERS */ - - #define PRIVILEGED_FUNCTION - #define PRIVILEGED_DATA - #define portUSING_MPU_WRAPPERS 0 - -#endif /* portUSING_MPU_WRAPPERS */ - - -#endif /* MPU_WRAPPERS_H */ - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but +only for ports that are using the MPU. */ +#ifdef portUSING_MPU_WRAPPERS + + /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is + included from queue.c or task.c to prevent it from having an effect within + those files. */ + #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + + #define xTaskGenericCreate MPU_xTaskGenericCreate + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define vTaskDelete MPU_vTaskDelete + #define vTaskDelayUntil MPU_vTaskDelayUntil + #define vTaskDelay MPU_vTaskDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define eTaskGetState MPU_eTaskGetState + #define vTaskSuspend MPU_vTaskSuspend + #define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended + #define vTaskResume MPU_vTaskResume + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskResumeAll MPU_xTaskResumeAll + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define vTaskList MPU_vTaskList + #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle + #define uxTaskGetSystemState MPU_uxTaskGetSystemState + + #define xQueueGenericCreate MPU_xQueueGenericCreate + #define xQueueCreateMutex MPU_xQueueCreateMutex + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueAltGenericSend MPU_xQueueAltGenericSend + #define xQueueAltGenericReceive MPU_xQueueAltGenericReceive + #define xQueueGenericReceive MPU_xQueueGenericReceive + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define vQueueDelete MPU_vQueueDelete + #define xQueueGenericReset MPU_xQueueGenericReset + #define xQueueCreateSet MPU_xQueueCreateSet + #define xQueueSelectFromSet MPU_xQueueSelectFromSet + #define xQueueAddToSet MPU_xQueueAddToSet + #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet + #define xQueuePeekFromISR MPU_xQueuePeekFromISR + + #define pvPortMalloc MPU_pvPortMalloc + #define vPortFree MPU_vPortFree + #define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize + #define vPortInitialiseBlocks MPU_vPortInitialiseBlocks + + #if configQUEUE_REGISTRY_SIZE > 0 + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #endif + + /* Remove the privileged function macro. */ + #define PRIVILEGED_FUNCTION + + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + + /* Ensure API functions go in the privileged execution section. */ + #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + + #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA + #define portUSING_MPU_WRAPPERS 0 + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ + diff --git a/include/freertos/portable.h b/include/freertos/portable.h index 31811b6d..56344e56 100644 --- a/include/freertos/portable.h +++ b/include/freertos/portable.h @@ -1,408 +1,408 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -/*----------------------------------------------------------- - * Portable layer API. Each function must be defined for each port. - *----------------------------------------------------------*/ - -#ifndef PORTABLE_H -#define PORTABLE_H - -/* Include the macro file relevant to the port being used. */ - -#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT - #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" - typedef void ( __interrupt __far *pxISR )(); -#endif - -#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT - #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" - typedef void ( __interrupt __far *pxISR )(); -#endif - -#ifdef GCC_MEGA_AVR - #include "../portable/GCC/ATMega323/portmacro.h" -#endif - -#ifdef IAR_MEGA_AVR - #include "../portable/IAR/ATMega323/portmacro.h" -#endif - -#ifdef MPLAB_PIC24_PORT - #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h" -#endif - -#ifdef MPLAB_DSPIC_PORT - #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h" -#endif - -#ifdef MPLAB_PIC18F_PORT - #include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h" -#endif - -#ifdef MPLAB_PIC32MX_PORT - #include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h" -#endif - -#ifdef _FEDPICC - #include "libFreeRTOS/Include/portmacro.h" -#endif - -#ifdef SDCC_CYGNAL - #include "../../Source/portable/SDCC/Cygnal/portmacro.h" -#endif - -#ifdef GCC_ARM7 - #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" -#endif - -#ifdef GCC_ARM7_ECLIPSE - #include "portmacro.h" -#endif - -#ifdef ROWLEY_LPC23xx - #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" -#endif - -#ifdef IAR_MSP430 - #include "..\..\Source\portable\IAR\MSP430\portmacro.h" -#endif - -#ifdef GCC_MSP430 - #include "../../Source/portable/GCC/MSP430F449/portmacro.h" -#endif - -#ifdef ROWLEY_MSP430 - #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" -#endif - -#ifdef ARM7_LPC21xx_KEIL_RVDS - #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" -#endif - -#ifdef SAM7_GCC - #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" -#endif - -#ifdef SAM7_IAR - #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" -#endif - -#ifdef SAM9XE_IAR - #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" -#endif - -#ifdef LPC2000_IAR - #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" -#endif - -#ifdef STR71X_IAR - #include "..\..\Source\portable\IAR\STR71x\portmacro.h" -#endif - -#ifdef STR75X_IAR - #include "..\..\Source\portable\IAR\STR75x\portmacro.h" -#endif - -#ifdef STR75X_GCC - #include "..\..\Source\portable\GCC\STR75x\portmacro.h" -#endif - -#ifdef STR91X_IAR - #include "..\..\Source\portable\IAR\STR91x\portmacro.h" -#endif - -#ifdef GCC_H8S - #include "../../Source/portable/GCC/H8S2329/portmacro.h" -#endif - -#ifdef GCC_AT91FR40008 - #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" -#endif - -#ifdef RVDS_ARMCM3_LM3S102 - #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" -#endif - -#ifdef GCC_ARMCM3_LM3S102 - #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" -#endif - -#ifdef GCC_ARMCM3 - #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" -#endif - -#ifdef IAR_ARM_CM3 - #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" -#endif - -#ifdef IAR_ARMCM3_LM - #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" -#endif - -#ifdef HCS12_CODE_WARRIOR - #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" -#endif - -#ifdef MICROBLAZE_GCC - #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" -#endif - -#ifdef TERN_EE - #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" -#endif - -#ifdef GCC_HCS12 - #include "../../Source/portable/GCC/HCS12/portmacro.h" -#endif - -#ifdef GCC_MCF5235 - #include "../../Source/portable/GCC/MCF5235/portmacro.h" -#endif - -#ifdef COLDFIRE_V2_GCC - #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" -#endif - -#ifdef COLDFIRE_V2_CODEWARRIOR - #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" -#endif - -#ifdef GCC_PPC405 - #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" -#endif - -#ifdef GCC_PPC440 - #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" -#endif - -#ifdef _16FX_SOFTUNE - #include "..\..\Source\portable\Softune\MB96340\portmacro.h" -#endif - -#ifdef BCC_INDUSTRIAL_PC_PORT - /* A short file name has to be used in place of the normal - FreeRTOSConfig.h when using the Borland compiler. */ - #include "frconfig.h" - #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" - typedef void ( __interrupt __far *pxISR )(); -#endif - -#ifdef BCC_FLASH_LITE_186_PORT - /* A short file name has to be used in place of the normal - FreeRTOSConfig.h when using the Borland compiler. */ - #include "frconfig.h" - #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" - typedef void ( __interrupt __far *pxISR )(); -#endif - -#ifdef __GNUC__ - #ifdef __AVR32_AVR32A__ - #include "portmacro.h" - #endif -#endif - -#ifdef __ICCAVR32__ - #ifdef __CORE__ - #if __CORE__ == __AVR32A__ - #include "portmacro.h" - #endif - #endif -#endif - -#ifdef __91467D - #include "portmacro.h" -#endif - -#ifdef __96340 - #include "portmacro.h" -#endif - - -#ifdef __IAR_V850ES_Fx3__ - #include "../../Source/portable/IAR/V850ES/portmacro.h" -#endif - -#ifdef __IAR_V850ES_Jx3__ - #include "../../Source/portable/IAR/V850ES/portmacro.h" -#endif - -#ifdef __IAR_V850ES_Jx3_L__ - #include "../../Source/portable/IAR/V850ES/portmacro.h" -#endif - -#ifdef __IAR_V850ES_Jx2__ - #include "../../Source/portable/IAR/V850ES/portmacro.h" -#endif - -#ifdef __IAR_V850ES_Hx2__ - #include "../../Source/portable/IAR/V850ES/portmacro.h" -#endif - -#ifdef __IAR_78K0R_Kx3__ - #include "../../Source/portable/IAR/78K0R/portmacro.h" -#endif - -#ifdef __IAR_78K0R_Kx3L__ - #include "../../Source/portable/IAR/78K0R/portmacro.h" -#endif - -/* Catch all to ensure portmacro.h is included in the build. Newer demos -have the path as part of the project options, rather than as relative from -the project location. If portENTER_CRITICAL() has not been defined then -portmacro.h has not yet been included - as every portmacro.h provides a -portENTER_CRITICAL() definition. Check the demo application for your demo -to find the path to the correct portmacro.h file. */ -#ifndef portENTER_CRITICAL - #include "portmacro.h" -#endif - -#if portBYTE_ALIGNMENT == 8 - #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) -#endif - -#if portBYTE_ALIGNMENT == 4 - #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) -#endif - -#if portBYTE_ALIGNMENT == 2 - #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) -#endif - -#if portBYTE_ALIGNMENT == 1 - #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) -#endif - -#ifndef portBYTE_ALIGNMENT_MASK - #error "Invalid portBYTE_ALIGNMENT definition" -#endif - -#ifndef portNUM_CONFIGURABLE_REGIONS - #define portNUM_CONFIGURABLE_REGIONS 1 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mpu_wrappers.h" - -/* - * Setup the stack of a new task so it is ready to be placed under the - * scheduler control. The registers have to be placed on the stack in - * the order that the port expects to find them. - * - */ -#if( portUSING_MPU_WRAPPERS == 1 ) - portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION; -#else - portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; -#endif - -/* - * Map to the memory management routines required for the port. - */ -/* for freeRTOS, MEMLEAK_DEBUG must be enabled. */ -#if 0 -void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; -void vPortFree( void *pv ) PRIVILEGED_FUNCTION; -#else -void *pvPortMalloc( size_t xSize, const char *file, unsigned line) PRIVILEGED_FUNCTION; -void vPortFree( void *pv, const char * file, unsigned line) PRIVILEGED_FUNCTION; -#endif - -void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; -size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; - -/* - * Setup the hardware ready for the scheduler to take control. This generally - * sets up a tick interrupt and sets timers for the correct tick frequency. - */ -portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION; - -/* - * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so - * the hardware is left in its original condition after the scheduler stops - * executing. - */ -void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; - -/* - * The structures and methods of manipulating the MPU are contained within the - * port layer. - * - * Fills the xMPUSettings structure with the memory region information - * contained in xRegions. - */ -#if( portUSING_MPU_WRAPPERS == 1 ) - struct xMEMORY_REGION; - void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth ) PRIVILEGED_FUNCTION; -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* PORTABLE_H */ - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Portable layer API. Each function must be defined for each port. + *----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Include the macro file relevant to the port being used. */ + +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT + #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT + #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef GCC_MEGA_AVR + #include "../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR + #include "../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT + #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT + #include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT + #include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT + #include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h" +#endif + +#ifdef _FEDPICC + #include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL + #include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 + #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE + #include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx + #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 + #include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 + #include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 + #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS + #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC + #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR + #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR + #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR + #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR + #include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR + #include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC + #include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR + #include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S + #include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 + #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 + #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR + #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC + #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE + #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 + #include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 + #include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC + #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR + #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 + #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 + #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE + #include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef __GNUC__ + #ifdef __AVR32_AVR32A__ + #include "portmacro.h" + #endif +#endif + +#ifdef __ICCAVR32__ + #ifdef __CORE__ + #if __CORE__ == __AVR32A__ + #include "portmacro.h" + #endif + #endif +#endif + +#ifdef __91467D + #include "portmacro.h" +#endif + +#ifdef __96340 + #include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +/* Catch all to ensure portmacro.h is included in the build. Newer demos +have the path as part of the project options, rather than as relative from +the project location. If portENTER_CRITICAL() has not been defined then +portmacro.h has not yet been included - as every portmacro.h provides a +portENTER_CRITICAL() definition. Check the demo application for your demo +to find the path to the correct portmacro.h file. */ +#ifndef portENTER_CRITICAL + #include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#endif + +#if portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#endif + +#if portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#endif + +#if portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#endif + +#ifndef portBYTE_ALIGNMENT_MASK + #error "Invalid portBYTE_ALIGNMENT definition" +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS + #define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mpu_wrappers.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION; +#else + portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; +#endif + +/* + * Map to the memory management routines required for the port. + */ +/* for freeRTOS, MEMLEAK_DEBUG must be enabled. */ +#if 0 +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void vPortFree( void *pv ) PRIVILEGED_FUNCTION; +#else +void *pvPortMalloc( size_t xSize, const char *file, unsigned line) PRIVILEGED_FUNCTION; +void vPortFree( void *pv, const char * file, unsigned line) PRIVILEGED_FUNCTION; +#endif + +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABLE_H */ + diff --git a/include/freertos/portmacro.h b/include/freertos/portmacro.h index 6eec264b..3d693b9c 100644 --- a/include/freertos/portmacro.h +++ b/include/freertos/portmacro.h @@ -1,199 +1,199 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - - -#ifndef PORTMACRO_H -#define PORTMACRO_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "c_types.h" -#include "espressif/esp_libc.h" -#include "esp8266/ets_sys.h" - -#include -#include "xtensa_rtos.h" - -/*----------------------------------------------------------- - * Port specific definitions. - * - * The settings in this file configure FreeRTOS correctly for the - * given hardware and compiler. - * - * These settings should not be altered. - *----------------------------------------------------------- - */ - -/* Type definitions. */ -#define portCHAR char -#define portFLOAT float -#define portDOUBLE double -#define portLONG long -#define portSHORT short -#define portSTACK_TYPE unsigned portLONG -#define portBASE_TYPE long - -typedef unsigned portLONG portTickType; -typedef unsigned int INT32U; -#define portMAX_DELAY ( portTickType ) 0xffffffff -/*-----------------------------------------------------------*/ - -/* Architecture specifics. */ -#define portSTACK_GROWTH ( -1 ) -#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) -#define portBYTE_ALIGNMENT 8 -/*-----------------------------------------------------------*/ - -/* Scheduler utilities. */ -extern void PendSV(char req); -//#define portYIELD() vPortYield() -#define portYIELD() PendSV(1) - -#if 0 -#define portEND_SWITCHING_ISR( xSwitchRequired ) \ - if(xSwitchRequired) PendSV(1) -#endif - -#define HDL_MAC_SIG_IN_LV1_ISR() PendSV(2) - -/* Task utilities. */ -#define portEND_SWITCHING_ISR( xSwitchRequired ) \ -{ \ -extern void vTaskSwitchContext( void ); \ - \ - if( xSwitchRequired ) \ - { \ - vTaskSwitchContext(); \ - } \ -} - - -/*-----------------------------------------------------------*/ -extern unsigned cpu_sr; - -/* Critical section management. */ -extern void vPortEnterCritical( void ); -extern void vPortExitCritical( void ); - -//DYC_ISR_DBG -void PortDisableInt_NoNest( void ); -void PortEnableInt_NoNest( void ); - -/* Disable interrupts, saving previous state in cpu_sr */ -#define portDISABLE_INTERRUPTS() \ - __asm__ volatile ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) : "=a" (cpu_sr) :: "memory") - -/* Restore interrupts to previous level saved in cpu_sr */ -#define portENABLE_INTERRUPTS() __asm__ volatile ("wsr %0, ps" :: "a" (cpu_sr) : "memory") - -#define portENTER_CRITICAL() vPortEnterCritical() -#define portEXIT_CRITICAL() vPortExitCritical() - -// no need to disable/enable lvl1 isr again in ISR -//#define portSET_INTERRUPT_MASK_FROM_ISR() PortDisableInt_NoNest() -//#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) PortEnableInt_NoNest() - - -/*-----------------------------------------------------------*/ - -/* Tickless idle/low power functionality. */ - -/*-----------------------------------------------------------*/ - -/* Port specific optimisations. */ - -/*-----------------------------------------------------------*/ - -/* Task function macros as described on the FreeRTOS.org WEB site. These are -not necessary for to use this port. They are defined so the common demo files -(which build with all the ports) will build. */ -#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) -#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) -/*-----------------------------------------------------------*/ - -void _xt_user_exit (void); -void _xt_tick_timer_init (void); -void _xt_isr_unmask (uint32 unmask); -void _xt_isr_mask (uint32 mask); -uint32 _xt_read_ints (void); -void _xt_clear_ints(uint32 mask); - -/* interrupt related */ -typedef void (* _xt_isr)(void *arg); - -void _xt_isr_attach (uint8 i, _xt_isr func, void *arg); - -typedef struct _xt_isr_entry_ { - _xt_isr handler; - void * arg; -} _xt_isr_entry; - -#ifdef __cplusplus -} -#endif - -#endif /* PORTMACRO_H */ - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "c_types.h" +#include "espressif/esp_libc.h" +#include "esp8266/ets_sys.h" + +#include +#include "xtensa_rtos.h" + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE unsigned portLONG +#define portBASE_TYPE long + +typedef unsigned portLONG portTickType; +typedef unsigned int INT32U; +#define portMAX_DELAY ( portTickType ) 0xffffffff +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +extern void PendSV(char req); +//#define portYIELD() vPortYield() +#define portYIELD() PendSV(1) + +#if 0 +#define portEND_SWITCHING_ISR( xSwitchRequired ) \ + if(xSwitchRequired) PendSV(1) +#endif + +#define HDL_MAC_SIG_IN_LV1_ISR() PendSV(2) + +/* Task utilities. */ +#define portEND_SWITCHING_ISR( xSwitchRequired ) \ +{ \ +extern void vTaskSwitchContext( void ); \ + \ + if( xSwitchRequired ) \ + { \ + vTaskSwitchContext(); \ + } \ +} + + +/*-----------------------------------------------------------*/ +extern unsigned cpu_sr; + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); + +//DYC_ISR_DBG +void PortDisableInt_NoNest( void ); +void PortEnableInt_NoNest( void ); + +/* Disable interrupts, saving previous state in cpu_sr */ +#define portDISABLE_INTERRUPTS() \ + __asm__ volatile ("rsil %0, " XTSTR(XCHAL_EXCM_LEVEL) : "=a" (cpu_sr) :: "memory") + +/* Restore interrupts to previous level saved in cpu_sr */ +#define portENABLE_INTERRUPTS() __asm__ volatile ("wsr %0, ps" :: "a" (cpu_sr) : "memory") + +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() + +// no need to disable/enable lvl1 isr again in ISR +//#define portSET_INTERRUPT_MASK_FROM_ISR() PortDisableInt_NoNest() +//#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) PortEnableInt_NoNest() + + +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ + +/*-----------------------------------------------------------*/ + +/* Port specific optimisations. */ + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +void _xt_user_exit (void); +void _xt_tick_timer_init (void); +void _xt_isr_unmask (uint32 unmask); +void _xt_isr_mask (uint32 mask); +uint32 _xt_read_ints (void); +void _xt_clear_ints(uint32 mask); + +/* interrupt related */ +typedef void (* _xt_isr)(void *arg); + +void _xt_isr_attach (uint8 i, _xt_isr func, void *arg); + +typedef struct _xt_isr_entry_ { + _xt_isr handler; + void * arg; +} _xt_isr_entry; + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/include/freertos/projdefs.h b/include/freertos/projdefs.h index 8a65e8b5..e2531bc0 100644 --- a/include/freertos/projdefs.h +++ b/include/freertos/projdefs.h @@ -1,88 +1,88 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -#ifndef PROJDEFS_H -#define PROJDEFS_H - -/* Defines the prototype to which task functions must conform. */ -typedef void (*pdTASK_CODE)( void * ); - -#define pdFALSE ( ( portBASE_TYPE ) 0 ) -#define pdTRUE ( ( portBASE_TYPE ) 1 ) - -#define pdPASS ( pdTRUE ) -#define pdFAIL ( pdFALSE ) -#define errQUEUE_EMPTY ( ( portBASE_TYPE ) 0 ) -#define errQUEUE_FULL ( ( portBASE_TYPE ) 0 ) - -/* Error definitions. */ -#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) -#define errNO_TASK_TO_RUN ( -2 ) -#define errQUEUE_BLOCKED ( -4 ) -#define errQUEUE_YIELD ( -5 ) - -#endif /* PROJDEFS_H */ - - - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* Defines the prototype to which task functions must conform. */ +typedef void (*pdTASK_CODE)( void * ); + +#define pdFALSE ( ( portBASE_TYPE ) 0 ) +#define pdTRUE ( ( portBASE_TYPE ) 1 ) + +#define pdPASS ( pdTRUE ) +#define pdFAIL ( pdFALSE ) +#define errQUEUE_EMPTY ( ( portBASE_TYPE ) 0 ) +#define errQUEUE_FULL ( ( portBASE_TYPE ) 0 ) + +/* Error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errNO_TASK_TO_RUN ( -2 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +#endif /* PROJDEFS_H */ + + + diff --git a/include/freertos/queue.h b/include/freertos/queue.h index c0f26309..3968cffd 100644 --- a/include/freertos/queue.h +++ b/include/freertos/queue.h @@ -1,1667 +1,1667 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - - -#ifndef QUEUE_H -#define QUEUE_H - -#ifndef INC_FREERTOS_H - #error "include FreeRTOS.h" must appear in source files before "include queue.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * Type by which queues are referenced. For example, a call to xQueueCreate() - * returns an xQueueHandle variable that can then be used as a parameter to - * xQueueSend(), xQueueReceive(), etc. - */ -typedef void * xQueueHandle; - -/** - * Type by which queue sets are referenced. For example, a call to - * xQueueCreateSet() returns an xQueueSet variable that can then be used as a - * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. - */ -typedef void * xQueueSetHandle; - -/** - * Queue sets can contain both queues and semaphores, so the - * xQueueSetMemberHandle is defined as a type to be used where a parameter or - * return value can be either an xQueueHandle or an xSemaphoreHandle. - */ -typedef void * xQueueSetMemberHandle; - -/* For internal use only. */ -#define queueSEND_TO_BACK ( ( portBASE_TYPE ) 0 ) -#define queueSEND_TO_FRONT ( ( portBASE_TYPE ) 1 ) -#define queueOVERWRITE ( ( portBASE_TYPE ) 2 ) - -/* For internal use only. These definitions *must* match those in queue.c. */ -#define queueQUEUE_TYPE_BASE ( ( unsigned char ) 0U ) -#define queueQUEUE_TYPE_SET ( ( unsigned char ) 0U ) -#define queueQUEUE_TYPE_MUTEX ( ( unsigned char ) 1U ) -#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( unsigned char ) 2U ) -#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( unsigned char ) 3U ) -#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( unsigned char ) 4U ) - -/** - * queue. h - *
- xQueueHandle xQueueCreate(
-							  unsigned portBASE_TYPE uxQueueLength,
-							  unsigned portBASE_TYPE uxItemSize
-						  );
- * 
- * - * Creates a new queue instance. This allocates the storage required by the - * new queue and returns a handle for the queue. - * - * @param uxQueueLength The maximum number of items that the queue can contain. - * - * @param uxItemSize The number of bytes each item in the queue will require. - * Items are queued by copy, not by reference, so this is the number of bytes - * that will be copied for each posted item. Each item on the queue must be - * the same size. - * - * @return If the queue is successfully create then a handle to the newly - * created queue is returned. If the queue cannot be created then 0 is - * returned. - * - * Example usage: -
- struct AMessage
- {
-	char ucMessageID;
-	char ucData[ 20 ];
- };
-
- void vATask( void *pvParameters )
- {
- xQueueHandle xQueue1, xQueue2;
-
-	// Create a queue capable of containing 10 unsigned long values.
-	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
-	if( xQueue1 == 0 )
-	{
-		// Queue was not created and must not be used.
-	}
-
-	// Create a queue capable of containing 10 pointers to AMessage structures.
-	// These should be passed by pointer as they contain a lot of data.
-	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
-	if( xQueue2 == 0 )
-	{
-		// Queue was not created and must not be used.
-	}
-
-	// ... Rest of task code.
- }
- 
- * \defgroup xQueueCreate xQueueCreate - * \ingroup QueueManagement - */ -#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE ) - -/** - * queue. h - *
- portBASE_TYPE xQueueSendToToFront(
-								   xQueueHandle	xQueue,
-								   const void	*	pvItemToQueue,
-								   portTickType	xTicksToWait
-							   );
- * 
- * - * This is a macro that calls xQueueGenericSend(). - * - * Post an item to the front of a queue. The item is queued by copy, not by - * reference. This function must not be called from an interrupt service - * routine. See xQueueSendFromISR () for an alternative which may be used - * in an ISR. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @param xTicksToWait The maximum amount of time the task should block - * waiting for space to become available on the queue, should it already - * be full. The call will return immediately if this is set to 0 and the - * queue is full. The time is defined in tick periods so the constant - * portTICK_RATE_MS should be used to convert to real time if this is required. - * - * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. - * - * Example usage: -
- struct AMessage
- {
-	char ucMessageID;
-	char ucData[ 20 ];
- } xMessage;
-
- unsigned long ulVar = 10UL;
-
- void vATask( void *pvParameters )
- {
- xQueueHandle xQueue1, xQueue2;
- struct AMessage *pxMessage;
-
-	// Create a queue capable of containing 10 unsigned long values.
-	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
-
-	// Create a queue capable of containing 10 pointers to AMessage structures.
-	// These should be passed by pointer as they contain a lot of data.
-	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
-
-	// ...
-
-	if( xQueue1 != 0 )
-	{
-		// Send an unsigned long.  Wait for 10 ticks for space to become
-		// available if necessary.
-		if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
-		{
-			// Failed to post the message, even after 10 ticks.
-		}
-	}
-
-	if( xQueue2 != 0 )
-	{
-		// Send a pointer to a struct AMessage object.  Don't block if the
-		// queue is already full.
-		pxMessage = & xMessage;
-		xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
-	}
-
-	// ... Rest of task code.
- }
- 
- * \defgroup xQueueSend xQueueSend - * \ingroup QueueManagement - */ -#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) - -/** - * queue. h - *
- portBASE_TYPE xQueueSendToBack(
-								   xQueueHandle	xQueue,
-								   const	void	*	pvItemToQueue,
-								   portTickType	xTicksToWait
-							   );
- * 
- * - * This is a macro that calls xQueueGenericSend(). - * - * Post an item to the back of a queue. The item is queued by copy, not by - * reference. This function must not be called from an interrupt service - * routine. See xQueueSendFromISR () for an alternative which may be used - * in an ISR. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @param xTicksToWait The maximum amount of time the task should block - * waiting for space to become available on the queue, should it already - * be full. The call will return immediately if this is set to 0 and the queue - * is full. The time is defined in tick periods so the constant - * portTICK_RATE_MS should be used to convert to real time if this is required. - * - * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. - * - * Example usage: -
- struct AMessage
- {
-	char ucMessageID;
-	char ucData[ 20 ];
- } xMessage;
-
- unsigned long ulVar = 10UL;
-
- void vATask( void *pvParameters )
- {
- xQueueHandle xQueue1, xQueue2;
- struct AMessage *pxMessage;
-
-	// Create a queue capable of containing 10 unsigned long values.
-	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
-
-	// Create a queue capable of containing 10 pointers to AMessage structures.
-	// These should be passed by pointer as they contain a lot of data.
-	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
-
-	// ...
-
-	if( xQueue1 != 0 )
-	{
-		// Send an unsigned long.  Wait for 10 ticks for space to become
-		// available if necessary.
-		if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
-		{
-			// Failed to post the message, even after 10 ticks.
-		}
-	}
-
-	if( xQueue2 != 0 )
-	{
-		// Send a pointer to a struct AMessage object.  Don't block if the
-		// queue is already full.
-		pxMessage = & xMessage;
-		xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
-	}
-
-	// ... Rest of task code.
- }
- 
- * \defgroup xQueueSend xQueueSend - * \ingroup QueueManagement - */ -#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) - -/** - * queue. h - *
- portBASE_TYPE xQueueSend(
-							  xQueueHandle xQueue,
-							  const void * pvItemToQueue,
-							  portTickType xTicksToWait
-						 );
- * 
- * - * This is a macro that calls xQueueGenericSend(). It is included for - * backward compatibility with versions of FreeRTOS.org that did not - * include the xQueueSendToFront() and xQueueSendToBack() macros. It is - * equivalent to xQueueSendToBack(). - * - * Post an item on a queue. The item is queued by copy, not by reference. - * This function must not be called from an interrupt service routine. - * See xQueueSendFromISR () for an alternative which may be used in an ISR. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @param xTicksToWait The maximum amount of time the task should block - * waiting for space to become available on the queue, should it already - * be full. The call will return immediately if this is set to 0 and the - * queue is full. The time is defined in tick periods so the constant - * portTICK_RATE_MS should be used to convert to real time if this is required. - * - * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. - * - * Example usage: -
- struct AMessage
- {
-	char ucMessageID;
-	char ucData[ 20 ];
- } xMessage;
-
- unsigned long ulVar = 10UL;
-
- void vATask( void *pvParameters )
- {
- xQueueHandle xQueue1, xQueue2;
- struct AMessage *pxMessage;
-
-	// Create a queue capable of containing 10 unsigned long values.
-	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
-
-	// Create a queue capable of containing 10 pointers to AMessage structures.
-	// These should be passed by pointer as they contain a lot of data.
-	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
-
-	// ...
-
-	if( xQueue1 != 0 )
-	{
-		// Send an unsigned long.  Wait for 10 ticks for space to become
-		// available if necessary.
-		if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
-		{
-			// Failed to post the message, even after 10 ticks.
-		}
-	}
-
-	if( xQueue2 != 0 )
-	{
-		// Send a pointer to a struct AMessage object.  Don't block if the
-		// queue is already full.
-		pxMessage = & xMessage;
-		xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
-	}
-
-	// ... Rest of task code.
- }
- 
- * \defgroup xQueueSend xQueueSend - * \ingroup QueueManagement - */ -#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) - -/** - * queue. h - *
- portBASE_TYPE xQueueOverwrite(
-							  xQueueHandle xQueue,
-							  const void * pvItemToQueue
-						 );
- * 
- * - * Only for use with queues that have a length of one - so the queue is either - * empty or full. - * - * Post an item on a queue. If the queue is already full then overwrite the - * value held in the queue. The item is queued by copy, not by reference. - * - * This function must not be called from an interrupt service routine. - * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. - * - * @param xQueue The handle of the queue to which the data is being sent. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and - * therefore has the same return values as xQueueSendToFront(). However, pdPASS - * is the only value that can be returned because xQueueOverwrite() will write - * to the queue even when the queue is already full. - * - * Example usage: -
-
- void vFunction( void *pvParameters )
- {
- xQueueHandle xQueue;
- unsigned long ulVarToSend, ulValReceived;
-
-	// Create a queue to hold one unsigned long value.  It is strongly
-	// recommended *not* to use xQueueOverwrite() on queues that can
-	// contain more than one value, and doing so will trigger an assertion
-	// if configASSERT() is defined.
-	xQueue = xQueueCreate( 1, sizeof( unsigned long ) );
-
-	// Write the value 10 to the queue using xQueueOverwrite().
-	ulVarToSend = 10;
-	xQueueOverwrite( xQueue, &ulVarToSend );
-
-	// Peeking the queue should now return 10, but leave the value 10 in
-	// the queue.  A block time of zero is used as it is known that the
-	// queue holds a value.
-	ulValReceived = 0;
-	xQueuePeek( xQueue, &ulValReceived, 0 );
-
-	if( ulValReceived != 10 )
-	{
-		// Error unless the item was removed by a different task.
-	}
-
-	// The queue is still full.  Use xQueueOverwrite() to overwrite the
-	// value held in the queue with 100.
-	ulVarToSend = 100;
-	xQueueOverwrite( xQueue, &ulVarToSend );
-
-	// This time read from the queue, leaving the queue empty once more.
-	// A block time of 0 is used again.
-	xQueueReceive( xQueue, &ulValReceived, 0 );
-
-	// The value read should be the last value written, even though the
-	// queue was already full when the value was written.
-	if( ulValReceived != 100 )
-	{
-		// Error!
-	}
-
-	// ...
-}
- 
- * \defgroup xQueueOverwrite xQueueOverwrite - * \ingroup QueueManagement - */ -#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) - - -/** - * queue. h - *
- portBASE_TYPE xQueueGenericSend(
-									xQueueHandle xQueue,
-									const void * pvItemToQueue,
-									portTickType xTicksToWait
-									portBASE_TYPE xCopyPosition
-								);
- * 
- * - * It is preferred that the macros xQueueSend(), xQueueSendToFront() and - * xQueueSendToBack() are used in place of calling this function directly. - * - * Post an item on a queue. The item is queued by copy, not by reference. - * This function must not be called from an interrupt service routine. - * See xQueueSendFromISR () for an alternative which may be used in an ISR. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @param xTicksToWait The maximum amount of time the task should block - * waiting for space to become available on the queue, should it already - * be full. The call will return immediately if this is set to 0 and the - * queue is full. The time is defined in tick periods so the constant - * portTICK_RATE_MS should be used to convert to real time if this is required. - * - * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the - * item at the back of the queue, or queueSEND_TO_FRONT to place the item - * at the front of the queue (for high priority messages). - * - * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. - * - * Example usage: -
- struct AMessage
- {
-	char ucMessageID;
-	char ucData[ 20 ];
- } xMessage;
-
- unsigned long ulVar = 10UL;
-
- void vATask( void *pvParameters )
- {
- xQueueHandle xQueue1, xQueue2;
- struct AMessage *pxMessage;
-
-	// Create a queue capable of containing 10 unsigned long values.
-	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
-
-	// Create a queue capable of containing 10 pointers to AMessage structures.
-	// These should be passed by pointer as they contain a lot of data.
-	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
-
-	// ...
-
-	if( xQueue1 != 0 )
-	{
-		// Send an unsigned long.  Wait for 10 ticks for space to become
-		// available if necessary.
-		if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )
-		{
-			// Failed to post the message, even after 10 ticks.
-		}
-	}
-
-	if( xQueue2 != 0 )
-	{
-		// Send a pointer to a struct AMessage object.  Don't block if the
-		// queue is already full.
-		pxMessage = & xMessage;
-		xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );
-	}
-
-	// ... Rest of task code.
- }
- 
- * \defgroup xQueueSend xQueueSend - * \ingroup QueueManagement - */ -signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; - -/** - * queue. h - *
- portBASE_TYPE xQueuePeek(
-							 xQueueHandle xQueue,
-							 void *pvBuffer,
-							 portTickType xTicksToWait
-						 );
- * - * This is a macro that calls the xQueueGenericReceive() function. - * - * Receive an item from a queue without removing the item from the queue. - * The item is received by copy so a buffer of adequate size must be - * provided. The number of bytes copied into the buffer was defined when - * the queue was created. - * - * Successfully received items remain on the queue so will be returned again - * by the next call, or a call to xQueueReceive(). - * - * This macro must not be used in an interrupt service routine. See - * xQueuePeekFromISR() for an alternative that can be called from an interrupt - * service routine. - * - * @param xQueue The handle to the queue from which the item is to be - * received. - * - * @param pvBuffer Pointer to the buffer into which the received item will - * be copied. - * - * @param xTicksToWait The maximum amount of time the task should block - * waiting for an item to receive should the queue be empty at the time - * of the call. The time is defined in tick periods so the constant - * portTICK_RATE_MS should be used to convert to real time if this is required. - * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue - * is empty. - * - * @return pdTRUE if an item was successfully received from the queue, - * otherwise pdFALSE. - * - * Example usage: -
- struct AMessage
- {
-	char ucMessageID;
-	char ucData[ 20 ];
- } xMessage;
-
- xQueueHandle xQueue;
-
- // Task to create a queue and post a value.
- void vATask( void *pvParameters )
- {
- struct AMessage *pxMessage;
-
-	// Create a queue capable of containing 10 pointers to AMessage structures.
-	// These should be passed by pointer as they contain a lot of data.
-	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
-	if( xQueue == 0 )
-	{
-		// Failed to create the queue.
-	}
-
-	// ...
-
-	// Send a pointer to a struct AMessage object.  Don't block if the
-	// queue is already full.
-	pxMessage = & xMessage;
-	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
-
-	// ... Rest of task code.
- }
-
- // Task to peek the data from the queue.
- void vADifferentTask( void *pvParameters )
- {
- struct AMessage *pxRxedMessage;
-
-	if( xQueue != 0 )
-	{
-		// Peek a message on the created queue.  Block for 10 ticks if a
-		// message is not immediately available.
-		if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
-		{
-			// pcRxedMessage now points to the struct AMessage variable posted
-			// by vATask, but the item still remains on the queue.
-		}
-	}
-
-	// ... Rest of task code.
- }
- 
- * \defgroup xQueueReceive xQueueReceive - * \ingroup QueueManagement - */ -#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE ) - -/** - * queue. h - *
- portBASE_TYPE xQueuePeekFromISR(
-									xQueueHandle xQueue,
-									void *pvBuffer,
-								);
- * - * A version of xQueuePeek() that can be called from an interrupt service - * routine (ISR). - * - * Receive an item from a queue without removing the item from the queue. - * The item is received by copy so a buffer of adequate size must be - * provided. The number of bytes copied into the buffer was defined when - * the queue was created. - * - * Successfully received items remain on the queue so will be returned again - * by the next call, or a call to xQueueReceive(). - * - * @param xQueue The handle to the queue from which the item is to be - * received. - * - * @param pvBuffer Pointer to the buffer into which the received item will - * be copied. - * - * @return pdTRUE if an item was successfully received from the queue, - * otherwise pdFALSE. - * - * \defgroup xQueuePeekFromISR xQueuePeekFromISR - * \ingroup QueueManagement - */ -signed portBASE_TYPE xQueuePeekFromISR( xQueueHandle xQueue, const void * const pvBuffer ) PRIVILEGED_FUNCTION; - -/** - * queue. h - *
- portBASE_TYPE xQueueReceive(
-								 xQueueHandle xQueue,
-								 void *pvBuffer,
-								 portTickType xTicksToWait
-							);
- * - * This is a macro that calls the xQueueGenericReceive() function. - * - * Receive an item from a queue. The item is received by copy so a buffer of - * adequate size must be provided. The number of bytes copied into the buffer - * was defined when the queue was created. - * - * Successfully received items are removed from the queue. - * - * This function must not be used in an interrupt service routine. See - * xQueueReceiveFromISR for an alternative that can. - * - * @param xQueue The handle to the queue from which the item is to be - * received. - * - * @param pvBuffer Pointer to the buffer into which the received item will - * be copied. - * - * @param xTicksToWait The maximum amount of time the task should block - * waiting for an item to receive should the queue be empty at the time - * of the call. xQueueReceive() will return immediately if xTicksToWait - * is zero and the queue is empty. The time is defined in tick periods so the - * constant portTICK_RATE_MS should be used to convert to real time if this is - * required. - * - * @return pdTRUE if an item was successfully received from the queue, - * otherwise pdFALSE. - * - * Example usage: -
- struct AMessage
- {
-	char ucMessageID;
-	char ucData[ 20 ];
- } xMessage;
-
- xQueueHandle xQueue;
-
- // Task to create a queue and post a value.
- void vATask( void *pvParameters )
- {
- struct AMessage *pxMessage;
-
-	// Create a queue capable of containing 10 pointers to AMessage structures.
-	// These should be passed by pointer as they contain a lot of data.
-	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
-	if( xQueue == 0 )
-	{
-		// Failed to create the queue.
-	}
-
-	// ...
-
-	// Send a pointer to a struct AMessage object.  Don't block if the
-	// queue is already full.
-	pxMessage = & xMessage;
-	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
-
-	// ... Rest of task code.
- }
-
- // Task to receive from the queue.
- void vADifferentTask( void *pvParameters )
- {
- struct AMessage *pxRxedMessage;
-
-	if( xQueue != 0 )
-	{
-		// Receive a message on the created queue.  Block for 10 ticks if a
-		// message is not immediately available.
-		if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
-		{
-			// pcRxedMessage now points to the struct AMessage variable posted
-			// by vATask.
-		}
-	}
-
-	// ... Rest of task code.
- }
- 
- * \defgroup xQueueReceive xQueueReceive - * \ingroup QueueManagement - */ -#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE ) - - -/** - * queue. h - *
- portBASE_TYPE xQueueGenericReceive(
-									   xQueueHandle	xQueue,
-									   void	*pvBuffer,
-									   portTickType	xTicksToWait
-									   portBASE_TYPE	xJustPeek
-									);
- * - * It is preferred that the macro xQueueReceive() be used rather than calling - * this function directly. - * - * Receive an item from a queue. The item is received by copy so a buffer of - * adequate size must be provided. The number of bytes copied into the buffer - * was defined when the queue was created. - * - * This function must not be used in an interrupt service routine. See - * xQueueReceiveFromISR for an alternative that can. - * - * @param xQueue The handle to the queue from which the item is to be - * received. - * - * @param pvBuffer Pointer to the buffer into which the received item will - * be copied. - * - * @param xTicksToWait The maximum amount of time the task should block - * waiting for an item to receive should the queue be empty at the time - * of the call. The time is defined in tick periods so the constant - * portTICK_RATE_MS should be used to convert to real time if this is required. - * xQueueGenericReceive() will return immediately if the queue is empty and - * xTicksToWait is 0. - * - * @param xJustPeek When set to true, the item received from the queue is not - * actually removed from the queue - meaning a subsequent call to - * xQueueReceive() will return the same item. When set to false, the item - * being received from the queue is also removed from the queue. - * - * @return pdTRUE if an item was successfully received from the queue, - * otherwise pdFALSE. - * - * Example usage: -
- struct AMessage
- {
-	char ucMessageID;
-	char ucData[ 20 ];
- } xMessage;
-
- xQueueHandle xQueue;
-
- // Task to create a queue and post a value.
- void vATask( void *pvParameters )
- {
- struct AMessage *pxMessage;
-
-	// Create a queue capable of containing 10 pointers to AMessage structures.
-	// These should be passed by pointer as they contain a lot of data.
-	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
-	if( xQueue == 0 )
-	{
-		// Failed to create the queue.
-	}
-
-	// ...
-
-	// Send a pointer to a struct AMessage object.  Don't block if the
-	// queue is already full.
-	pxMessage = & xMessage;
-	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
-
-	// ... Rest of task code.
- }
-
- // Task to receive from the queue.
- void vADifferentTask( void *pvParameters )
- {
- struct AMessage *pxRxedMessage;
-
-	if( xQueue != 0 )
-	{
-		// Receive a message on the created queue.  Block for 10 ticks if a
-		// message is not immediately available.
-		if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
-		{
-			// pcRxedMessage now points to the struct AMessage variable posted
-			// by vATask.
-		}
-	}
-
-	// ... Rest of task code.
- }
- 
- * \defgroup xQueueReceive xQueueReceive - * \ingroup QueueManagement - */ -signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek ) PRIVILEGED_FUNCTION; - -/** - * queue. h - *
unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );
- * - * Return the number of messages stored in a queue. - * - * @param xQueue A handle to the queue being queried. - * - * @return The number of messages available in the queue. - * - * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting - * \ingroup QueueManagement - */ -unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION; - -/** - * queue. h - *
void vQueueDelete( xQueueHandle xQueue );
- * - * Delete a queue - freeing all the memory allocated for storing of items - * placed on the queue. - * - * @param xQueue A handle to the queue to be deleted. - * - * \defgroup vQueueDelete vQueueDelete - * \ingroup QueueManagement - */ -void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; - -/** - * queue. h - *
- portBASE_TYPE xQueueSendToFrontFromISR(
-										 xQueueHandle xQueue,
-										 const void *pvItemToQueue,
-										 portBASE_TYPE *pxHigherPriorityTaskWoken
-									  );
- 
- * - * This is a macro that calls xQueueGenericSendFromISR(). - * - * Post an item to the front of a queue. It is safe to use this macro from - * within an interrupt service routine. - * - * Items are queued by copy not reference so it is preferable to only - * queue small items, especially when called from an ISR. In most cases - * it would be preferable to store a pointer to the item being queued. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set - * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task - * to unblock, and the unblocked task has a priority higher than the currently - * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then - * a context switch should be requested before the interrupt is exited. - * - * @return pdTRUE if the data was successfully sent to the queue, otherwise - * errQUEUE_FULL. - * - * Example usage for buffered IO (where the ISR can obtain more than one value - * per call): -
- void vBufferISR( void )
- {
- char cIn;
- portBASE_TYPE xHigherPrioritTaskWoken;
-
-	// We have not woken a task at the start of the ISR.
-	xHigherPriorityTaskWoken = pdFALSE;
-
-	// Loop until the buffer is empty.
-	do
-	{
-		// Obtain a byte from the buffer.
-		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
-
-		// Post the byte.
-		xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
-
-	} while( portINPUT_BYTE( BUFFER_COUNT ) );
-
-	// Now the buffer is empty we can switch context if necessary.
-	if( xHigherPriorityTaskWoken )
-	{
-		taskYIELD ();
-	}
- }
- 
- * - * \defgroup xQueueSendFromISR xQueueSendFromISR - * \ingroup QueueManagement - */ -#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) - - -/** - * queue. h - *
- portBASE_TYPE xQueueSendToBackFromISR(
-										 xQueueHandle xQueue,
-										 const void *pvItemToQueue,
-										 portBASE_TYPE *pxHigherPriorityTaskWoken
-									  );
- 
- * - * This is a macro that calls xQueueGenericSendFromISR(). - * - * Post an item to the back of a queue. It is safe to use this macro from - * within an interrupt service routine. - * - * Items are queued by copy not reference so it is preferable to only - * queue small items, especially when called from an ISR. In most cases - * it would be preferable to store a pointer to the item being queued. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set - * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task - * to unblock, and the unblocked task has a priority higher than the currently - * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then - * a context switch should be requested before the interrupt is exited. - * - * @return pdTRUE if the data was successfully sent to the queue, otherwise - * errQUEUE_FULL. - * - * Example usage for buffered IO (where the ISR can obtain more than one value - * per call): -
- void vBufferISR( void )
- {
- char cIn;
- portBASE_TYPE xHigherPriorityTaskWoken;
-
-	// We have not woken a task at the start of the ISR.
-	xHigherPriorityTaskWoken = pdFALSE;
-
-	// Loop until the buffer is empty.
-	do
-	{
-		// Obtain a byte from the buffer.
-		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
-
-		// Post the byte.
-		xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
-
-	} while( portINPUT_BYTE( BUFFER_COUNT ) );
-
-	// Now the buffer is empty we can switch context if necessary.
-	if( xHigherPriorityTaskWoken )
-	{
-		taskYIELD ();
-	}
- }
- 
- * - * \defgroup xQueueSendFromISR xQueueSendFromISR - * \ingroup QueueManagement - */ -#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) - -/** - * queue. h - *
- portBASE_TYPE xQueueOverwriteFromISR(
-							  xQueueHandle xQueue,
-							  const void * pvItemToQueue,
-							  portBASE_TYPE *pxHigherPriorityTaskWoken
-						 );
- * 
- * - * A version of xQueueOverwrite() that can be used in an interrupt service - * routine (ISR). - * - * Only for use with queues that can hold a single item - so the queue is either - * empty or full. - * - * Post an item on a queue. If the queue is already full then overwrite the - * value held in the queue. The item is queued by copy, not by reference. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set - * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task - * to unblock, and the unblocked task has a priority higher than the currently - * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then - * a context switch should be requested before the interrupt is exited. - * - * @return xQueueOverwriteFromISR() is a macro that calls - * xQueueGenericSendFromISR(), and therefore has the same return values as - * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be - * returned because xQueueOverwriteFromISR() will write to the queue even when - * the queue is already full. - * - * Example usage: -
-
- xQueueHandle xQueue;
- 
- void vFunction( void *pvParameters )
- {
- 	// Create a queue to hold one unsigned long value.  It is strongly
-	// recommended *not* to use xQueueOverwriteFromISR() on queues that can
-	// contain more than one value, and doing so will trigger an assertion
-	// if configASSERT() is defined.
-	xQueue = xQueueCreate( 1, sizeof( unsigned long ) );
-}
-
-void vAnInterruptHandler( void )
-{
-// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
-portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
-unsigned long ulVarToSend, ulValReceived;
-
-	// Write the value 10 to the queue using xQueueOverwriteFromISR().
-	ulVarToSend = 10;
-	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
-
-	// The queue is full, but calling xQueueOverwriteFromISR() again will still
-	// pass because the value held in the queue will be overwritten with the
-	// new value.
-	ulVarToSend = 100;
-	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
-
-	// Reading from the queue will now return 100.
-
-	// ...
-	
-	if( xHigherPrioritytaskWoken == pdTRUE )
-	{
-		// Writing to the queue caused a task to unblock and the unblocked task
-		// has a priority higher than or equal to the priority of the currently
-		// executing task (the task this interrupt interrupted).  Perform a context
-		// switch so this interrupt returns directly to the unblocked task.
-		portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
-	}
-}
- 
- * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR - * \ingroup QueueManagement - */ -#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) - -/** - * queue. h - *
- portBASE_TYPE xQueueSendFromISR(
-									 xQueueHandle xQueue,
-									 const void *pvItemToQueue,
-									 portBASE_TYPE *pxHigherPriorityTaskWoken
-								);
- 
- * - * This is a macro that calls xQueueGenericSendFromISR(). It is included - * for backward compatibility with versions of FreeRTOS.org that did not - * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() - * macros. - * - * Post an item to the back of a queue. It is safe to use this function from - * within an interrupt service routine. - * - * Items are queued by copy not reference so it is preferable to only - * queue small items, especially when called from an ISR. In most cases - * it would be preferable to store a pointer to the item being queued. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set - * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task - * to unblock, and the unblocked task has a priority higher than the currently - * running task. If xQueueSendFromISR() sets this value to pdTRUE then - * a context switch should be requested before the interrupt is exited. - * - * @return pdTRUE if the data was successfully sent to the queue, otherwise - * errQUEUE_FULL. - * - * Example usage for buffered IO (where the ISR can obtain more than one value - * per call): -
- void vBufferISR( void )
- {
- char cIn;
- portBASE_TYPE xHigherPriorityTaskWoken;
-
-	// We have not woken a task at the start of the ISR.
-	xHigherPriorityTaskWoken = pdFALSE;
-
-	// Loop until the buffer is empty.
-	do
-	{
-		// Obtain a byte from the buffer.
-		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
-
-		// Post the byte.
-		xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
-
-	} while( portINPUT_BYTE( BUFFER_COUNT ) );
-
-	// Now the buffer is empty we can switch context if necessary.
-	if( xHigherPriorityTaskWoken )
-	{
-		// Actual macro used here is port specific.
-		taskYIELD_FROM_ISR ();
-	}
- }
- 
- * - * \defgroup xQueueSendFromISR xQueueSendFromISR - * \ingroup QueueManagement - */ -#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) - -/** - * queue. h - *
- portBASE_TYPE xQueueGenericSendFromISR(
-										   xQueueHandle		xQueue,
-										   const	void	*pvItemToQueue,
-										   portBASE_TYPE	*pxHigherPriorityTaskWoken,
-										   portBASE_TYPE	xCopyPosition
-									   );
- 
- * - * It is preferred that the macros xQueueSendFromISR(), - * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place - * of calling this function directly. - * - * Post an item on a queue. It is safe to use this function from within an - * interrupt service routine. - * - * Items are queued by copy not reference so it is preferable to only - * queue small items, especially when called from an ISR. In most cases - * it would be preferable to store a pointer to the item being queued. - * - * @param xQueue The handle to the queue on which the item is to be posted. - * - * @param pvItemToQueue A pointer to the item that is to be placed on the - * queue. The size of the items the queue will hold was defined when the - * queue was created, so this many bytes will be copied from pvItemToQueue - * into the queue storage area. - * - * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set - * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task - * to unblock, and the unblocked task has a priority higher than the currently - * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then - * a context switch should be requested before the interrupt is exited. - * - * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the - * item at the back of the queue, or queueSEND_TO_FRONT to place the item - * at the front of the queue (for high priority messages). - * - * @return pdTRUE if the data was successfully sent to the queue, otherwise - * errQUEUE_FULL. - * - * Example usage for buffered IO (where the ISR can obtain more than one value - * per call): -
- void vBufferISR( void )
- {
- char cIn;
- portBASE_TYPE xHigherPriorityTaskWokenByPost;
-
-	// We have not woken a task at the start of the ISR.
-	xHigherPriorityTaskWokenByPost = pdFALSE;
-
-	// Loop until the buffer is empty.
-	do
-	{
-		// Obtain a byte from the buffer.
-		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
-
-		// Post each byte.
-		xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
-
-	} while( portINPUT_BYTE( BUFFER_COUNT ) );
-
-	// Now the buffer is empty we can switch context if necessary.  Note that the
-	// name of the yield function required is port specific.
-	if( xHigherPriorityTaskWokenByPost )
-	{
-		taskYIELD_YIELD_FROM_ISR();
-	}
- }
- 
- * - * \defgroup xQueueSendFromISR xQueueSendFromISR - * \ingroup QueueManagement - */ -signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle xQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; - -/** - * queue. h - *
- portBASE_TYPE xQueueReceiveFromISR(
-									   xQueueHandle	xQueue,
-									   void	*pvBuffer,
-									   portBASE_TYPE *pxTaskWoken
-								   );
- * 
- * - * Receive an item from a queue. It is safe to use this function from within an - * interrupt service routine. - * - * @param xQueue The handle to the queue from which the item is to be - * received. - * - * @param pvBuffer Pointer to the buffer into which the received item will - * be copied. - * - * @param pxTaskWoken A task may be blocked waiting for space to become - * available on the queue. If xQueueReceiveFromISR causes such a task to - * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will - * remain unchanged. - * - * @return pdTRUE if an item was successfully received from the queue, - * otherwise pdFALSE. - * - * Example usage: -
-
- xQueueHandle xQueue;
-
- // Function to create a queue and post some values.
- void vAFunction( void *pvParameters )
- {
- char cValueToPost;
- const portTickType xBlockTime = ( portTickType )0xff;
-
-	// Create a queue capable of containing 10 characters.
-	xQueue = xQueueCreate( 10, sizeof( char ) );
-	if( xQueue == 0 )
-	{
-		// Failed to create the queue.
-	}
-
-	// ...
-
-	// Post some characters that will be used within an ISR.  If the queue
-	// is full then this task will block for xBlockTime ticks.
-	cValueToPost = 'a';
-	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
-	cValueToPost = 'b';
-	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
-
-	// ... keep posting characters ... this task may block when the queue
-	// becomes full.
-
-	cValueToPost = 'c';
-	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
- }
-
- // ISR that outputs all the characters received on the queue.
- void vISR_Routine( void )
- {
- portBASE_TYPE xTaskWokenByReceive = pdFALSE;
- char cRxedChar;
-
-	while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
-	{
-		// A character was received.  Output the character now.
-		vOutputCharacter( cRxedChar );
-
-		// If removing the character from the queue woke the task that was
-		// posting onto the queue cTaskWokenByReceive will have been set to
-		// pdTRUE.  No matter how many times this loop iterates only one
-		// task will be woken.
-	}
-
-	if( cTaskWokenByPost != ( char ) pdFALSE;
-	{
-		taskYIELD ();
-	}
- }
- 
- * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR - * \ingroup QueueManagement - */ -signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle xQueue, const void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; - -/* - * Utilities to query queues that are safe to use from an ISR. These utilities - * should be used only from witin an ISR, or within a critical section. - */ -signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION; -signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION; -unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION; - - -/* - * xQueueAltGenericSend() is an alternative version of xQueueGenericSend(). - * Likewise xQueueAltGenericReceive() is an alternative version of - * xQueueGenericReceive(). - * - * The source code that implements the alternative (Alt) API is much - * simpler because it executes everything from within a critical section. - * This is the approach taken by many other RTOSes, but FreeRTOS.org has the - * preferred fully featured API too. The fully featured API has more - * complex code that takes longer to execute, but makes much less use of - * critical sections. Therefore the alternative API sacrifices interrupt - * responsiveness to gain execution speed, whereas the fully featured API - * sacrifices execution speed to ensure better interrupt responsiveness. - */ -signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ); -signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ); -#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) -#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) -#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE ) -#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE ) - -/* - * The functions defined above are for passing data to and from tasks. The - * functions below are the equivalents for passing data to and from - * co-routines. - * - * These functions are called from the co-routine macro implementation and - * should not be called directly from application code. Instead use the macro - * wrappers defined within croutine.h. - */ -signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle xQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ); -signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle xQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ); -signed portBASE_TYPE xQueueCRSend( xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait ); -signed portBASE_TYPE xQueueCRReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait ); - -/* - * For internal use only. Use xSemaphoreCreateMutex(), - * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling - * these functions directly. - */ -xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ) PRIVILEGED_FUNCTION; -xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION; -void* xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION; - -/* - * For internal use only. Use xSemaphoreTakeMutexRecursive() or - * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. - */ -portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION; -portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ) PRIVILEGED_FUNCTION; - -/* - * Reset a queue back to its original empty state. pdPASS is returned if the - * queue is successfully reset. pdFAIL is returned if the queue could not be - * reset because there are tasks blocked on the queue waiting to either - * receive from the queue or send to the queue. - */ -#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE ) - -/* - * The registry is provided as a means for kernel aware debuggers to - * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add - * a queue, semaphore or mutex handle to the registry if you want the handle - * to be available to a kernel aware debugger. If you are not using a kernel - * aware debugger then this function can be ignored. - * - * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the - * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 - * within FreeRTOSConfig.h for the registry to be available. Its value - * does not effect the number of queues, semaphores and mutexes that can be - * created - just the number that the registry can hold. - * - * @param xQueue The handle of the queue being added to the registry. This - * is the handle returned by a call to xQueueCreate(). Semaphore and mutex - * handles can also be passed in here. - * - * @param pcName The name to be associated with the handle. This is the - * name that the kernel aware debugger will display. - */ -#if configQUEUE_REGISTRY_SIZE > 0 - void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ) PRIVILEGED_FUNCTION; -#endif - -/* - * The registry is provided as a means for kernel aware debuggers to - * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add - * a queue, semaphore or mutex handle to the registry if you want the handle - * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to - * remove the queue, semaphore or mutex from the register. If you are not using - * a kernel aware debugger then this function can be ignored. - * - * @param xQueue The handle of the queue being removed from the registry. - */ -#if configQUEUE_REGISTRY_SIZE > 0 - void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; -#endif - -/* - * Generic version of the queue creation function, which is in turn called by - * any queue, semaphore or mutex creation function or macro. - */ -xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION; - -/* - * Queue sets provide a mechanism to allow a task to block (pend) on a read - * operation from multiple queues or semaphores simultaneously. - * - * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this - * function. - * - * A queue set must be explicitly created using a call to xQueueCreateSet() - * before it can be used. Once created, standard FreeRTOS queues and semaphores - * can be added to the set using calls to xQueueAddToSet(). - * xQueueSelectFromSet() is then used to determine which, if any, of the queues - * or semaphores contained in the set is in a state where a queue read or - * semaphore take operation would be successful. - * - * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html - * for reasons why queue sets are very rarely needed in practice as there are - * simpler methods of blocking on multiple objects. - * - * Note 2: Blocking on a queue set that contains a mutex will not cause the - * mutex holder to inherit the priority of the blocked task. - * - * Note 3: An additional 4 bytes of RAM is required for each space in a every - * queue added to a queue set. Therefore counting semaphores that have a high - * maximum count value should not be added to a queue set. - * - * Note 4: A receive (in the case of a queue) or take (in the case of a - * semaphore) operation must not be performed on a member of a queue set unless - * a call to xQueueSelectFromSet() has first returned a handle to that set member. - * - * @param uxEventQueueLength Queue sets store events that occur on - * the queues and semaphores contained in the set. uxEventQueueLength specifies - * the maximum number of events that can be queued at once. To be absolutely - * certain that events are not lost uxEventQueueLength should be set to the - * total sum of the length of the queues added to the set, where binary - * semaphores and mutexes have a length of 1, and counting semaphores have a - * length set by their maximum count value. Examples: - * + If a queue set is to hold a queue of length 5, another queue of length 12, - * and a binary semaphore, then uxEventQueueLength should be set to - * (5 + 12 + 1), or 18. - * + If a queue set is to hold three binary semaphores then uxEventQueueLength - * should be set to (1 + 1 + 1 ), or 3. - * + If a queue set is to hold a counting semaphore that has a maximum count of - * 5, and a counting semaphore that has a maximum count of 3, then - * uxEventQueueLength should be set to (5 + 3), or 8. - * - * @return If the queue set is created successfully then a handle to the created - * queue set is returned. Otherwise NULL is returned. - */ -xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION; - -/* - * Adds a queue or semaphore to a queue set that was previously created by a - * call to xQueueCreateSet(). - * - * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this - * function. - * - * Note 1: A receive (in the case of a queue) or take (in the case of a - * semaphore) operation must not be performed on a member of a queue set unless - * a call to xQueueSelectFromSet() has first returned a handle to that set member. - * - * @param xQueueOrSemaphore The handle of the queue or semaphore being added to - * the queue set (cast to an xQueueSetMemberHandle type). - * - * @param xQueueSet The handle of the queue set to which the queue or semaphore - * is being added. - * - * @return If the queue or semaphore was successfully added to the queue set - * then pdPASS is returned. If the queue could not be successfully added to the - * queue set because it is already a member of a different queue set then pdFAIL - * is returned. - */ -portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION; - -/* - * Removes a queue or semaphore from a queue set. A queue or semaphore can only - * be removed from a set if the queue or semaphore is empty. - * - * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this - * function. - * - * @param xQueueOrSemaphore The handle of the queue or semaphore being removed - * from the queue set (cast to an xQueueSetMemberHandle type). - * - * @param xQueueSet The handle of the queue set in which the queue or semaphore - * is included. - * - * @return If the queue or semaphore was successfully removed from the queue set - * then pdPASS is returned. If the queue was not in the queue set, or the - * queue (or semaphore) was not empty, then pdFAIL is returned. - */ -portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION; - -/* - * xQueueSelectFromSet() selects from the members of a queue set a queue or - * semaphore that either contains data (in the case of a queue) or is available - * to take (in the case of a semaphore). xQueueSelectFromSet() effectively - * allows a task to block (pend) on a read operation on all the queues and - * semaphores in a queue set simultaneously. - * - * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this - * function. - * - * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html - * for reasons why queue sets are very rarely needed in practice as there are - * simpler methods of blocking on multiple objects. - * - * Note 2: Blocking on a queue set that contains a mutex will not cause the - * mutex holder to inherit the priority of the blocked task. - * - * Note 3: A receive (in the case of a queue) or take (in the case of a - * semaphore) operation must not be performed on a member of a queue set unless - * a call to xQueueSelectFromSet() has first returned a handle to that set member. - * - * @param xQueueSet The queue set on which the task will (potentially) block. - * - * @param xBlockTimeTicks The maximum time, in ticks, that the calling task will - * remain in the Blocked state (with other tasks executing) to wait for a member - * of the queue set to be ready for a successful queue read or semaphore take - * operation. - * - * @return xQueueSelectFromSet() will return the handle of a queue (cast to - * a xQueueSetMemberHandle type) contained in the queue set that contains data, - * or the handle of a semaphore (cast to a xQueueSetMemberHandle type) contained - * in the queue set that is available, or NULL if no such queue or semaphore - * exists before before the specified block time expires. - */ -xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION; - -/* - * A version of xQueueSelectFromSet() that can be used from an ISR. - */ -xQueueSetMemberHandle xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION; - -/* Not public API functions. */ -void vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; -portBASE_TYPE xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION; -void vQueueSetQueueNumber( xQueueHandle xQueue, unsigned char ucQueueNumber ) PRIVILEGED_FUNCTION; -unsigned char ucQueueGetQueueNumber( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; -unsigned char ucQueueGetQueueType( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; - - -#ifdef __cplusplus -} -#endif - -#endif /* QUEUE_H */ - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include queue.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate() + * returns an xQueueHandle variable that can then be used as a parameter to + * xQueueSend(), xQueueReceive(), etc. + */ +typedef void * xQueueHandle; + +/** + * Type by which queue sets are referenced. For example, a call to + * xQueueCreateSet() returns an xQueueSet variable that can then be used as a + * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. + */ +typedef void * xQueueSetHandle; + +/** + * Queue sets can contain both queues and semaphores, so the + * xQueueSetMemberHandle is defined as a type to be used where a parameter or + * return value can be either an xQueueHandle or an xSemaphoreHandle. + */ +typedef void * xQueueSetMemberHandle; + +/* For internal use only. */ +#define queueSEND_TO_BACK ( ( portBASE_TYPE ) 0 ) +#define queueSEND_TO_FRONT ( ( portBASE_TYPE ) 1 ) +#define queueOVERWRITE ( ( portBASE_TYPE ) 2 ) + +/* For internal use only. These definitions *must* match those in queue.c. */ +#define queueQUEUE_TYPE_BASE ( ( unsigned char ) 0U ) +#define queueQUEUE_TYPE_SET ( ( unsigned char ) 0U ) +#define queueQUEUE_TYPE_MUTEX ( ( unsigned char ) 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( unsigned char ) 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( unsigned char ) 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( unsigned char ) 4U ) + +/** + * queue. h + *
+ xQueueHandle xQueueCreate(
+							  unsigned portBASE_TYPE uxQueueLength,
+							  unsigned portBASE_TYPE uxItemSize
+						  );
+ * 
+ * + * Creates a new queue instance. This allocates the storage required by the + * new queue and returns a handle for the queue. + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+	if( xQueue1 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue2 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToToFront(
+								   xQueueHandle	xQueue,
+								   const void	*	pvItemToQueue,
+								   portTickType	xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToBack(
+								   xQueueHandle	xQueue,
+								   const	void	*	pvItemToQueue,
+								   portTickType	xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueSend(
+							  xQueueHandle xQueue,
+							  const void * pvItemToQueue,
+							  portTickType xTicksToWait
+						 );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueOverwrite(
+							  xQueueHandle xQueue,
+							  const void * pvItemToQueue
+						 );
+ * 
+ * + * Only for use with queues that have a length of one - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * This function must not be called from an interrupt service routine. + * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle of the queue to which the data is being sent. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and + * therefore has the same return values as xQueueSendToFront(). However, pdPASS + * is the only value that can be returned because xQueueOverwrite() will write + * to the queue even when the queue is already full. + * + * Example usage: +
+
+ void vFunction( void *pvParameters )
+ {
+ xQueueHandle xQueue;
+ unsigned long ulVarToSend, ulValReceived;
+
+	// Create a queue to hold one unsigned long value.  It is strongly
+	// recommended *not* to use xQueueOverwrite() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( unsigned long ) );
+
+	// Write the value 10 to the queue using xQueueOverwrite().
+	ulVarToSend = 10;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// Peeking the queue should now return 10, but leave the value 10 in
+	// the queue.  A block time of zero is used as it is known that the
+	// queue holds a value.
+	ulValReceived = 0;
+	xQueuePeek( xQueue, &ulValReceived, 0 );
+
+	if( ulValReceived != 10 )
+	{
+		// Error unless the item was removed by a different task.
+	}
+
+	// The queue is still full.  Use xQueueOverwrite() to overwrite the
+	// value held in the queue with 100.
+	ulVarToSend = 100;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// This time read from the queue, leaving the queue empty once more.
+	// A block time of 0 is used again.
+	xQueueReceive( xQueue, &ulValReceived, 0 );
+
+	// The value read should be the last value written, even though the
+	// queue was already full when the value was written.
+	if( ulValReceived != 100 )
+	{
+		// Error!
+	}
+
+	// ...
+}
+ 
+ * \defgroup xQueueOverwrite xQueueOverwrite + * \ingroup QueueManagement + */ +#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) + + +/** + * queue. h + *
+ portBASE_TYPE xQueueGenericSend(
+									xQueueHandle xQueue,
+									const void * pvItemToQueue,
+									portTickType xTicksToWait
+									portBASE_TYPE xCopyPosition
+								);
+ * 
+ * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ unsigned long ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ xQueueHandle xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 unsigned long values.
+	xQueue1 = xQueueCreate( 10, sizeof( unsigned long ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an unsigned long.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( portTickType ) 10, queueSEND_TO_BACK ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( portTickType ) 0, queueSEND_TO_BACK );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ portBASE_TYPE xQueuePeek(
+							 xQueueHandle xQueue,
+							 void *pvBuffer,
+							 portTickType xTicksToWait
+						 );
+ * + * This is a macro that calls the xQueueGenericReceive() function. + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. See + * xQueuePeekFromISR() for an alternative that can be called from an interrupt + * service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Peek a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueuePeek( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask, but the item still remains on the queue.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE ) + +/** + * queue. h + *
+ portBASE_TYPE xQueuePeekFromISR(
+									xQueueHandle xQueue,
+									void *pvBuffer,
+								);
+ * + * A version of xQueuePeek() that can be called from an interrupt service + * routine (ISR). + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * \defgroup xQueuePeekFromISR xQueuePeekFromISR + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueuePeekFromISR( xQueueHandle xQueue, const void * const pvBuffer ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ portBASE_TYPE xQueueReceive(
+								 xQueueHandle xQueue,
+								 void *pvBuffer,
+								 portTickType xTicksToWait
+							);
+ * + * This is a macro that calls the xQueueGenericReceive() function. + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_RATE_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE ) + + +/** + * queue. h + *
+ portBASE_TYPE xQueueGenericReceive(
+									   xQueueHandle	xQueue,
+									   void	*pvBuffer,
+									   portTickType	xTicksToWait
+									   portBASE_TYPE	xJustPeek
+									);
+ * + * It is preferred that the macro xQueueReceive() be used rather than calling + * this function directly. + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_RATE_MS should be used to convert to real time if this is required. + * xQueueGenericReceive() will return immediately if the queue is empty and + * xTicksToWait is 0. + * + * @param xJustPeek When set to true, the item received from the queue is not + * actually removed from the queue - meaning a subsequent call to + * xQueueReceive() will return the same item. When set to false, the item + * being received from the queue is also removed from the queue. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ xQueueHandle xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( portTickType ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( portTickType ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeek ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue );
+ * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
void vQueueDelete( xQueueHandle xQueue );
+ * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \defgroup vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToFrontFromISR(
+										 xQueueHandle xQueue,
+										 const void *pvItemToQueue,
+										 portBASE_TYPE *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPrioritTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) + + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendToBackFromISR(
+										 xQueueHandle xQueue,
+										 const void *pvItemToQueue,
+										 portBASE_TYPE *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueOverwriteFromISR(
+							  xQueueHandle xQueue,
+							  const void * pvItemToQueue,
+							  portBASE_TYPE *pxHigherPriorityTaskWoken
+						 );
+ * 
+ * + * A version of xQueueOverwrite() that can be used in an interrupt service + * routine (ISR). + * + * Only for use with queues that can hold a single item - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return xQueueOverwriteFromISR() is a macro that calls + * xQueueGenericSendFromISR(), and therefore has the same return values as + * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be + * returned because xQueueOverwriteFromISR() will write to the queue even when + * the queue is already full. + * + * Example usage: +
+
+ xQueueHandle xQueue;
+ 
+ void vFunction( void *pvParameters )
+ {
+ 	// Create a queue to hold one unsigned long value.  It is strongly
+	// recommended *not* to use xQueueOverwriteFromISR() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( unsigned long ) );
+}
+
+void vAnInterruptHandler( void )
+{
+// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
+portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
+unsigned long ulVarToSend, ulValReceived;
+
+	// Write the value 10 to the queue using xQueueOverwriteFromISR().
+	ulVarToSend = 10;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// The queue is full, but calling xQueueOverwriteFromISR() again will still
+	// pass because the value held in the queue will be overwritten with the
+	// new value.
+	ulVarToSend = 100;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// Reading from the queue will now return 100.
+
+	// ...
+	
+	if( xHigherPrioritytaskWoken == pdTRUE )
+	{
+		// Writing to the queue caused a task to unblock and the unblocked task
+		// has a priority higher than or equal to the priority of the currently
+		// executing task (the task this interrupt interrupted).  Perform a context
+		// switch so this interrupt returns directly to the unblocked task.
+		portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
+	}
+}
+ 
+ * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR + * \ingroup QueueManagement + */ +#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueSendFromISR(
+									 xQueueHandle xQueue,
+									 const void *pvItemToQueue,
+									 portBASE_TYPE *pxHigherPriorityTaskWoken
+								);
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		// Actual macro used here is port specific.
+		taskYIELD_FROM_ISR ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ portBASE_TYPE xQueueGenericSendFromISR(
+										   xQueueHandle		xQueue,
+										   const	void	*pvItemToQueue,
+										   portBASE_TYPE	*pxHigherPriorityTaskWoken,
+										   portBASE_TYPE	xCopyPosition
+									   );
+ 
+ * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ portBASE_TYPE xHigherPriorityTaskWokenByPost;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWokenByPost = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post each byte.
+		xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.  Note that the
+	// name of the yield function required is port specific.
+	if( xHigherPriorityTaskWokenByPost )
+	{
+		taskYIELD_YIELD_FROM_ISR();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle xQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ portBASE_TYPE xQueueReceiveFromISR(
+									   xQueueHandle	xQueue,
+									   void	*pvBuffer,
+									   portBASE_TYPE *pxTaskWoken
+								   );
+ * 
+ * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxTaskWoken A task may be blocked waiting for space to become + * available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+
+ xQueueHandle xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const portTickType xBlockTime = ( portTickType )0xff;
+
+	// Create a queue capable of containing 10 characters.
+	xQueue = xQueueCreate( 10, sizeof( char ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Post some characters that will be used within an ISR.  If the queue
+	// is full then this task will block for xBlockTime ticks.
+	cValueToPost = 'a';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+	cValueToPost = 'b';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+
+	// ... keep posting characters ... this task may block when the queue
+	// becomes full.
+
+	cValueToPost = 'c';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xBlockTime );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ portBASE_TYPE xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+	while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+	{
+		// A character was received.  Output the character now.
+		vOutputCharacter( cRxedChar );
+
+		// If removing the character from the queue woke the task that was
+		// posting onto the queue cTaskWokenByReceive will have been set to
+		// pdTRUE.  No matter how many times this loop iterates only one
+		// task will be woken.
+	}
+
+	if( cTaskWokenByPost != ( char ) pdFALSE;
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle xQueue, const void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* + * Utilities to query queues that are safe to use from an ISR. These utilities + * should be used only from witin an ISR, or within a critical section. + */ +signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION; +signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION; +unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle xQueue ) PRIVILEGED_FUNCTION; + + +/* + * xQueueAltGenericSend() is an alternative version of xQueueGenericSend(). + * Likewise xQueueAltGenericReceive() is an alternative version of + * xQueueGenericReceive(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ); +signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ); +#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) +#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) +#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE ) +#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE ) + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle xQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ); +signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle xQueue, void *pvBuffer, signed portBASE_TYPE *pxTaskWoken ); +signed portBASE_TYPE xQueueCRSend( xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait ); +signed portBASE_TYPE xQueueCRReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait ); + +/* + * For internal use only. Use xSemaphoreCreateMutex(), + * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling + * these functions directly. + */ +xQueueHandle xQueueCreateMutex( unsigned char ucQueueType ) PRIVILEGED_FUNCTION; +xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) PRIVILEGED_FUNCTION; +void* xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) PRIVILEGED_FUNCTION; +portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle pxMutex ) PRIVILEGED_FUNCTION; + +/* + * Reset a queue back to its original empty state. pdPASS is returned if the + * queue is successfully reset. pdFAIL is returned if the queue could not be + * reset because there are tasks blocked on the queue waiting to either + * receive from the queue or send to the queue. + */ +#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE ) + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not effect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. + */ +#if configQUEUE_REGISTRY_SIZE > 0 + void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName ) PRIVILEGED_FUNCTION; +#endif + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to + * remove the queue, semaphore or mutex from the register. If you are not using + * a kernel aware debugger then this function can be ignored. + * + * @param xQueue The handle of the queue being removed from the registry. + */ +#if configQUEUE_REGISTRY_SIZE > 0 + void vQueueUnregisterQueue( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the queue creation function, which is in turn called by + * any queue, semaphore or mutex creation function or macro. + */ +xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) PRIVILEGED_FUNCTION; + +/* + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * before it can be used. Once created, standard FreeRTOS queues and semaphores + * can be added to the set using calls to xQueueAddToSet(). + * xQueueSelectFromSet() is then used to determine which, if any, of the queues + * or semaphores contained in the set is in a state where a queue read or + * semaphore take operation would be successful. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. Otherwise NULL is returned. + */ +xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION; + +/* + * Adds a queue or semaphore to a queue set that was previously created by a + * call to xQueueCreateSet(). + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being added to + * the queue set (cast to an xQueueSetMemberHandle type). + * + * @param xQueueSet The handle of the queue set to which the queue or semaphore + * is being added. + * + * @return If the queue or semaphore was successfully added to the queue set + * then pdPASS is returned. If the queue could not be successfully added to the + * queue set because it is already a member of a different queue set then pdFAIL + * is returned. + */ +portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * Removes a queue or semaphore from a queue set. A queue or semaphore can only + * be removed from a set if the queue or semaphore is empty. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being removed + * from the queue set (cast to an xQueueSetMemberHandle type). + * + * @param xQueueSet The handle of the queue set in which the queue or semaphore + * is included. + * + * @return If the queue or semaphore was successfully removed from the queue set + * then pdPASS is returned. If the queue was not in the queue set, or the + * queue (or semaphore) was not empty, then pdFAIL is returned. + */ +portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * xQueueSelectFromSet() selects from the members of a queue set a queue or + * semaphore that either contains data (in the case of a queue) or is available + * to take (in the case of a semaphore). xQueueSelectFromSet() effectively + * allows a task to block (pend) on a read operation on all the queues and + * semaphores in a queue set simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueSet The queue set on which the task will (potentially) block. + * + * @param xBlockTimeTicks The maximum time, in ticks, that the calling task will + * remain in the Blocked state (with other tasks executing) to wait for a member + * of the queue set to be ready for a successful queue read or semaphore take + * operation. + * + * @return xQueueSelectFromSet() will return the handle of a queue (cast to + * a xQueueSetMemberHandle type) contained in the queue set that contains data, + * or the handle of a semaphore (cast to a xQueueSetMemberHandle type) contained + * in the queue set that is available, or NULL if no such queue or semaphore + * exists before before the specified block time expires. + */ +xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION; + +/* + * A version of xQueueSelectFromSet() that can be used from an ISR. + */ +xQueueSetMemberHandle xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION; + +/* Not public API functions. */ +void vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; +portBASE_TYPE xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION; +void vQueueSetQueueNumber( xQueueHandle xQueue, unsigned char ucQueueNumber ) PRIVILEGED_FUNCTION; +unsigned char ucQueueGetQueueNumber( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; +unsigned char ucQueueGetQueueType( xQueueHandle xQueue ) PRIVILEGED_FUNCTION; + + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + diff --git a/include/freertos/semphr.h b/include/freertos/semphr.h index c1c7f611..04957f5c 100644 --- a/include/freertos/semphr.h +++ b/include/freertos/semphr.h @@ -1,785 +1,785 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -#ifndef SEMAPHORE_H -#define SEMAPHORE_H - -#ifndef INC_FREERTOS_H - #error "include FreeRTOS.h" must appear in source files before "include semphr.h" -#endif - -#include "queue.h" - -typedef xQueueHandle xSemaphoreHandle; - -#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1U ) -#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0U ) -#define semGIVE_BLOCK_TIME ( ( portTickType ) 0U ) - - -/** - * semphr. h - *
vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )
- * - * Macro that implements a semaphore by using the existing queue mechanism. - * The queue length is 1 as this is a binary semaphore. The data size is 0 - * as we don't want to actually store any data - we just want to know if the - * queue is empty or full. - * - * This type of semaphore can be used for pure synchronisation between tasks or - * between an interrupt and a task. The semaphore need not be given back once - * obtained, so one task/interrupt can continuously 'give' the semaphore while - * another continuously 'takes' the semaphore. For this reason this type of - * semaphore does not use a priority inheritance mechanism. For an alternative - * that does use priority inheritance see xSemaphoreCreateMutex(). - * - * @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle. - * - * Example usage: -
- xSemaphoreHandle xSemaphore;
-
- void vATask( void * pvParameters )
- {
-    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
-    // This is a macro so pass the variable in directly.
-    vSemaphoreCreateBinary( xSemaphore );
-
-    if( xSemaphore != NULL )
-    {
-        // The semaphore was created successfully.
-        // The semaphore can now be used.  
-    }
- }
- 
- * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary - * \ingroup Semaphores - */ -#define vSemaphoreCreateBinary( xSemaphore ) \ - { \ - ( xSemaphore ) = xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ - if( ( xSemaphore ) != NULL ) \ - { \ - ( void ) xSemaphoreGive( ( xSemaphore ) ); \ - } \ - } - -/** - * semphr. h - *
xSemaphoreTake( 
- *                   xSemaphoreHandle xSemaphore, 
- *                   portTickType xBlockTime 
- *               )
- * - * Macro to obtain a semaphore. The semaphore must have previously been - * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or - * xSemaphoreCreateCounting(). - * - * @param xSemaphore A handle to the semaphore being taken - obtained when - * the semaphore was created. - * - * @param xBlockTime The time in ticks to wait for the semaphore to become - * available. The macro portTICK_RATE_MS can be used to convert this to a - * real time. A block time of zero can be used to poll the semaphore. A block - * time of portMAX_DELAY can be used to block indefinitely (provided - * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). - * - * @return pdTRUE if the semaphore was obtained. pdFALSE - * if xBlockTime expired without the semaphore becoming available. - * - * Example usage: -
- xSemaphoreHandle xSemaphore = NULL;
-
- // A task that creates a semaphore.
- void vATask( void * pvParameters )
- {
-    // Create the semaphore to guard a shared resource.
-    vSemaphoreCreateBinary( xSemaphore );
- }
-
- // A task that uses the semaphore.
- void vAnotherTask( void * pvParameters )
- {
-    // ... Do other things.
-
-    if( xSemaphore != NULL )
-    {
-        // See if we can obtain the semaphore.  If the semaphore is not available
-        // wait 10 ticks to see if it becomes free.	
-        if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
-        {
-            // We were able to obtain the semaphore and can now access the
-            // shared resource.
-
-            // ...
-
-            // We have finished accessing the shared resource.  Release the 
-            // semaphore.
-            xSemaphoreGive( xSemaphore );
-        }
-        else
-        {
-            // We could not obtain the semaphore and can therefore not access
-            // the shared resource safely.
-        }
-    }
- }
- 
- * \defgroup xSemaphoreTake xSemaphoreTake - * \ingroup Semaphores - */ -#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) - -/** - * semphr. h - * xSemaphoreTakeRecursive( - * xSemaphoreHandle xMutex, - * portTickType xBlockTime - * ) - * - * Macro to recursively obtain, or 'take', a mutex type semaphore. - * The mutex must have previously been created using a call to - * xSemaphoreCreateRecursiveMutex(); - * - * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this - * macro to be available. - * - * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). - * - * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex - * doesn't become available again until the owner has called - * xSemaphoreGiveRecursive() for each successful 'take' request. For example, - * if a task successfully 'takes' the same mutex 5 times then the mutex will - * not be available to any other task until it has also 'given' the mutex back - * exactly five times. - * - * @param xMutex A handle to the mutex being obtained. This is the - * handle returned by xSemaphoreCreateRecursiveMutex(); - * - * @param xBlockTime The time in ticks to wait for the semaphore to become - * available. The macro portTICK_RATE_MS can be used to convert this to a - * real time. A block time of zero can be used to poll the semaphore. If - * the task already owns the semaphore then xSemaphoreTakeRecursive() will - * return immediately no matter what the value of xBlockTime. - * - * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime - * expired without the semaphore becoming available. - * - * Example usage: -
- xSemaphoreHandle xMutex = NULL;
-
- // A task that creates a mutex.
- void vATask( void * pvParameters )
- {
-    // Create the mutex to guard a shared resource.
-    xMutex = xSemaphoreCreateRecursiveMutex();
- }
-
- // A task that uses the mutex.
- void vAnotherTask( void * pvParameters )
- {
-    // ... Do other things.
-
-    if( xMutex != NULL )
-    {
-        // See if we can obtain the mutex.  If the mutex is not available
-        // wait 10 ticks to see if it becomes free.	
-        if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
-        {
-            // We were able to obtain the mutex and can now access the
-            // shared resource.
-
-            // ...
-            // For some reason due to the nature of the code further calls to 
-			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
-			// code these would not be just sequential calls as this would make
-			// no sense.  Instead the calls are likely to be buried inside
-			// a more complex call structure.
-            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
-            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
-
-            // The mutex has now been 'taken' three times, so will not be 
-			// available to another task until it has also been given back
-			// three times.  Again it is unlikely that real code would have
-			// these calls sequentially, but instead buried in a more complex
-			// call structure.  This is just for illustrative purposes.
-            xSemaphoreGiveRecursive( xMutex );
-			xSemaphoreGiveRecursive( xMutex );
-			xSemaphoreGiveRecursive( xMutex );
-
-			// Now the mutex can be taken by other tasks.
-        }
-        else
-        {
-            // We could not obtain the mutex and can therefore not access
-            // the shared resource safely.
-        }
-    }
- }
- 
- * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive - * \ingroup Semaphores - */ -#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) - - -/* - * xSemaphoreAltTake() is an alternative version of xSemaphoreTake(). - * - * The source code that implements the alternative (Alt) API is much - * simpler because it executes everything from within a critical section. - * This is the approach taken by many other RTOSes, but FreeRTOS.org has the - * preferred fully featured API too. The fully featured API has more - * complex code that takes longer to execute, but makes much less use of - * critical sections. Therefore the alternative API sacrifices interrupt - * responsiveness to gain execution speed, whereas the fully featured API - * sacrifices execution speed to ensure better interrupt responsiveness. - */ -#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) - -/** - * semphr. h - *
xSemaphoreGive( xSemaphoreHandle xSemaphore )
- * - * Macro to release a semaphore. The semaphore must have previously been - * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or - * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). - * - * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for - * an alternative which can be used from an ISR. - * - * This macro must also not be used on semaphores created using - * xSemaphoreCreateRecursiveMutex(). - * - * @param xSemaphore A handle to the semaphore being released. This is the - * handle returned when the semaphore was created. - * - * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. - * Semaphores are implemented using queues. An error can occur if there is - * no space on the queue to post a message - indicating that the - * semaphore was not first obtained correctly. - * - * Example usage: -
- xSemaphoreHandle xSemaphore = NULL;
-
- void vATask( void * pvParameters )
- {
-    // Create the semaphore to guard a shared resource.
-    vSemaphoreCreateBinary( xSemaphore );
-
-    if( xSemaphore != NULL )
-    {
-        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
-        {
-            // We would expect this call to fail because we cannot give
-            // a semaphore without first "taking" it!
-        }
-
-        // Obtain the semaphore - don't block if the semaphore is not
-        // immediately available.
-        if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
-        {
-            // We now have the semaphore and can access the shared resource.
-
-            // ...
-
-            // We have finished accessing the shared resource so can free the
-            // semaphore.
-            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
-            {
-                // We would not expect this call to fail because we must have
-                // obtained the semaphore to get here.
-            }
-        }
-    }
- }
- 
- * \defgroup xSemaphoreGive xSemaphoreGive - * \ingroup Semaphores - */ -#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) - -/** - * semphr. h - *
xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )
- * - * Macro to recursively release, or 'give', a mutex type semaphore. - * The mutex must have previously been created using a call to - * xSemaphoreCreateRecursiveMutex(); - * - * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this - * macro to be available. - * - * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). - * - * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex - * doesn't become available again until the owner has called - * xSemaphoreGiveRecursive() for each successful 'take' request. For example, - * if a task successfully 'takes' the same mutex 5 times then the mutex will - * not be available to any other task until it has also 'given' the mutex back - * exactly five times. - * - * @param xMutex A handle to the mutex being released, or 'given'. This is the - * handle returned by xSemaphoreCreateMutex(); - * - * @return pdTRUE if the semaphore was given. - * - * Example usage: -
- xSemaphoreHandle xMutex = NULL;
-
- // A task that creates a mutex.
- void vATask( void * pvParameters )
- {
-    // Create the mutex to guard a shared resource.
-    xMutex = xSemaphoreCreateRecursiveMutex();
- }
-
- // A task that uses the mutex.
- void vAnotherTask( void * pvParameters )
- {
-    // ... Do other things.
-
-    if( xMutex != NULL )
-    {
-        // See if we can obtain the mutex.  If the mutex is not available
-        // wait 10 ticks to see if it becomes free.	
-        if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
-        {
-            // We were able to obtain the mutex and can now access the
-            // shared resource.
-
-            // ...
-            // For some reason due to the nature of the code further calls to 
-			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
-			// code these would not be just sequential calls as this would make
-			// no sense.  Instead the calls are likely to be buried inside
-			// a more complex call structure.
-            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
-            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
-
-            // The mutex has now been 'taken' three times, so will not be 
-			// available to another task until it has also been given back
-			// three times.  Again it is unlikely that real code would have
-			// these calls sequentially, it would be more likely that the calls
-			// to xSemaphoreGiveRecursive() would be called as a call stack
-			// unwound.  This is just for demonstrative purposes.
-            xSemaphoreGiveRecursive( xMutex );
-			xSemaphoreGiveRecursive( xMutex );
-			xSemaphoreGiveRecursive( xMutex );
-
-			// Now the mutex can be taken by other tasks.
-        }
-        else
-        {
-            // We could not obtain the mutex and can therefore not access
-            // the shared resource safely.
-        }
-    }
- }
- 
- * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive - * \ingroup Semaphores - */ -#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) - -/* - * xSemaphoreAltGive() is an alternative version of xSemaphoreGive(). - * - * The source code that implements the alternative (Alt) API is much - * simpler because it executes everything from within a critical section. - * This is the approach taken by many other RTOSes, but FreeRTOS.org has the - * preferred fully featured API too. The fully featured API has more - * complex code that takes longer to execute, but makes much less use of - * critical sections. Therefore the alternative API sacrifices interrupt - * responsiveness to gain execution speed, whereas the fully featured API - * sacrifices execution speed to ensure better interrupt responsiveness. - */ -#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) - -/** - * semphr. h - *
- xSemaphoreGiveFromISR( 
-                          xSemaphoreHandle xSemaphore, 
-                          signed portBASE_TYPE *pxHigherPriorityTaskWoken
-                      )
- * - * Macro to release a semaphore. The semaphore must have previously been - * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). - * - * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) - * must not be used with this macro. - * - * This macro can be used from an ISR. - * - * @param xSemaphore A handle to the semaphore being released. This is the - * handle returned when the semaphore was created. - * - * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set - * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task - * to unblock, and the unblocked task has a priority higher than the currently - * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then - * a context switch should be requested before the interrupt is exited. - * - * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. - * - * Example usage: -
- \#define LONG_TIME 0xffff
- \#define TICKS_TO_WAIT	10
- xSemaphoreHandle xSemaphore = NULL;
-
- // Repetitive task.
- void vATask( void * pvParameters )
- {
-    for( ;; )
-    {
-        // We want this task to run every 10 ticks of a timer.  The semaphore 
-        // was created before this task was started.
-
-        // Block waiting for the semaphore to become available.
-        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
-        {
-            // It is time to execute.
-
-            // ...
-
-            // We have finished our task.  Return to the top of the loop where
-            // we will block on the semaphore until it is time to execute 
-            // again.  Note when using the semaphore for synchronisation with an
-			// ISR in this manner there is no need to 'give' the semaphore back.
-        }
-    }
- }
-
- // Timer ISR
- void vTimerISR( void * pvParameters )
- {
- static unsigned char ucLocalTickCount = 0;
- static signed portBASE_TYPE xHigherPriorityTaskWoken;
-
-    // A timer tick has occurred.
-
-    // ... Do other time functions.
-
-    // Is it time for vATask () to run?
-	xHigherPriorityTaskWoken = pdFALSE;
-    ucLocalTickCount++;
-    if( ucLocalTickCount >= TICKS_TO_WAIT )
-    {
-        // Unblock the task by releasing the semaphore.
-        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
-
-        // Reset the count so we release the semaphore again in 10 ticks time.
-        ucLocalTickCount = 0;
-    }
-
-    if( xHigherPriorityTaskWoken != pdFALSE )
-    {
-        // We can force a context switch here.  Context switching from an
-        // ISR uses port specific syntax.  Check the demo task for your port
-        // to find the syntax required.
-    }
- }
- 
- * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR - * \ingroup Semaphores - */ -#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) - -/** - * semphr. h - *
- xSemaphoreTakeFromISR( 
-                          xSemaphoreHandle xSemaphore, 
-                          signed portBASE_TYPE *pxHigherPriorityTaskWoken
-                      )
- * - * Macro to take a semaphore from an ISR. The semaphore must have - * previously been created with a call to vSemaphoreCreateBinary() or - * xSemaphoreCreateCounting(). - * - * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) - * must not be used with this macro. - * - * This macro can be used from an ISR, however taking a semaphore from an ISR - * is not a common operation. It is likely to only be useful when taking a - * counting semaphore when an interrupt is obtaining an object from a resource - * pool (when the semaphore count indicates the number of resources available). - * - * @param xSemaphore A handle to the semaphore being taken. This is the - * handle returned when the semaphore was created. - * - * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set - * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task - * to unblock, and the unblocked task has a priority higher than the currently - * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then - * a context switch should be requested before the interrupt is exited. - * - * @return pdTRUE if the semaphore was successfully taken, otherwise - * pdFALSE - */ -#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) - -/** - * semphr. h - *
xSemaphoreHandle xSemaphoreCreateMutex( void )
- * - * Macro that implements a mutex semaphore by using the existing queue - * mechanism. - * - * Mutexes created using this macro can be accessed using the xSemaphoreTake() - * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and - * xSemaphoreGiveRecursive() macros should not be used. - * - * This type of semaphore uses a priority inheritance mechanism so a task - * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the - * semaphore it is no longer required. - * - * Mutex type semaphores cannot be used from within interrupt service routines. - * - * See vSemaphoreCreateBinary() for an alternative implementation that can be - * used for pure synchronisation (where one task or interrupt always 'gives' the - * semaphore and another always 'takes' the semaphore) and from within interrupt - * service routines. - * - * @return xSemaphore Handle to the created mutex semaphore. Should be of type - * xSemaphoreHandle. - * - * Example usage: -
- xSemaphoreHandle xSemaphore;
-
- void vATask( void * pvParameters )
- {
-    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
-    // This is a macro so pass the variable in directly.
-    xSemaphore = xSemaphoreCreateMutex();
-
-    if( xSemaphore != NULL )
-    {
-        // The semaphore was created successfully.
-        // The semaphore can now be used.  
-    }
- }
- 
- * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex - * \ingroup Semaphores - */ -#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) - - -/** - * semphr. h - *
xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )
- * - * Macro that implements a recursive mutex by using the existing queue - * mechanism. - * - * Mutexes created using this macro can be accessed using the - * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The - * xSemaphoreTake() and xSemaphoreGive() macros should not be used. - * - * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex - * doesn't become available again until the owner has called - * xSemaphoreGiveRecursive() for each successful 'take' request. For example, - * if a task successfully 'takes' the same mutex 5 times then the mutex will - * not be available to any other task until it has also 'given' the mutex back - * exactly five times. - * - * This type of semaphore uses a priority inheritance mechanism so a task - * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the - * semaphore it is no longer required. - * - * Mutex type semaphores cannot be used from within interrupt service routines. - * - * See vSemaphoreCreateBinary() for an alternative implementation that can be - * used for pure synchronisation (where one task or interrupt always 'gives' the - * semaphore and another always 'takes' the semaphore) and from within interrupt - * service routines. - * - * @return xSemaphore Handle to the created mutex semaphore. Should be of type - * xSemaphoreHandle. - * - * Example usage: -
- xSemaphoreHandle xSemaphore;
-
- void vATask( void * pvParameters )
- {
-    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
-    // This is a macro so pass the variable in directly.
-    xSemaphore = xSemaphoreCreateRecursiveMutex();
-
-    if( xSemaphore != NULL )
-    {
-        // The semaphore was created successfully.
-        // The semaphore can now be used.  
-    }
- }
- 
- * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex - * \ingroup Semaphores - */ -#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) - -/** - * semphr. h - *
xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )
- * - * Macro that creates a counting semaphore by using the existing - * queue mechanism. - * - * Counting semaphores are typically used for two things: - * - * 1) Counting events. - * - * In this usage scenario an event handler will 'give' a semaphore each time - * an event occurs (incrementing the semaphore count value), and a handler - * task will 'take' a semaphore each time it processes an event - * (decrementing the semaphore count value). The count value is therefore - * the difference between the number of events that have occurred and the - * number that have been processed. In this case it is desirable for the - * initial count value to be zero. - * - * 2) Resource management. - * - * In this usage scenario the count value indicates the number of resources - * available. To obtain control of a resource a task must first obtain a - * semaphore - decrementing the semaphore count value. When the count value - * reaches zero there are no free resources. When a task finishes with the - * resource it 'gives' the semaphore back - incrementing the semaphore count - * value. In this case it is desirable for the initial count value to be - * equal to the maximum count value, indicating that all resources are free. - * - * @param uxMaxCount The maximum count value that can be reached. When the - * semaphore reaches this value it can no longer be 'given'. - * - * @param uxInitialCount The count value assigned to the semaphore when it is - * created. - * - * @return Handle to the created semaphore. Null if the semaphore could not be - * created. - * - * Example usage: -
- xSemaphoreHandle xSemaphore;
-
- void vATask( void * pvParameters )
- {
- xSemaphoreHandle xSemaphore = NULL;
-
-    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
-    // The max value to which the semaphore can count should be 10, and the
-    // initial value assigned to the count should be 0.
-    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
-
-    if( xSemaphore != NULL )
-    {
-        // The semaphore was created successfully.
-        // The semaphore can now be used.  
-    }
- }
- 
- * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting - * \ingroup Semaphores - */ -#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) - -/** - * semphr. h - *
void vSemaphoreDelete( xSemaphoreHandle xSemaphore );
- * - * Delete a semaphore. This function must be used with care. For example, - * do not delete a mutex type semaphore if the mutex is held by a task. - * - * @param xSemaphore A handle to the semaphore to be deleted. - * - * \defgroup vSemaphoreDelete vSemaphoreDelete - * \ingroup Semaphores - */ -#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) ( xSemaphore ) ) - -/** - * semphr.h - *
xTaskHandle xSemaphoreGetMutexHolder( xSemaphoreHandle xMutex );
- * - * If xMutex is indeed a mutex type semaphore, return the current mutex holder. - * If xMutex is not a mutex type semaphore, or the mutex is available (not held - * by a task), return NULL. - * - * Note: This Is is a good way of determining if the calling task is the mutex - * holder, but not a good way of determining the identity of the mutex holder as - * the holder may change between the function exiting and the returned value - * being tested. - */ -#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) - -#endif /* SEMAPHORE_H */ - - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include semphr.h" +#endif + +#include "queue.h" + +typedef xQueueHandle xSemaphoreHandle; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0U ) +#define semGIVE_BLOCK_TIME ( ( portTickType ) 0U ) + + +/** + * semphr. h + *
vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )
+ * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#define vSemaphoreCreateBinary( xSemaphore ) \ + { \ + ( xSemaphore ) = xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + ( void ) xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } + +/** + * semphr. h + *
xSemaphoreTake( 
+ *                   xSemaphoreHandle xSemaphore, 
+ *                   portTickType xBlockTime 
+ *               )
+ * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_RATE_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    vSemaphoreCreateBinary( xSemaphore );
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xSemaphore != NULL )
+    {
+        // See if we can obtain the semaphore.  If the semaphore is not available
+        // wait 10 ticks to see if it becomes free.	
+        if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the semaphore and can now access the
+            // shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource.  Release the 
+            // semaphore.
+            xSemaphoreGive( xSemaphore );
+        }
+        else
+        {
+            // We could not obtain the semaphore and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) + +/** + * semphr. h + * xSemaphoreTakeRecursive( + * xSemaphoreHandle xMutex, + * portTickType xBlockTime + * ) + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_RATE_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: +
+ xSemaphoreHandle xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.	
+        if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to 
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be 
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, but instead buried in a more complex
+			// call structure.  This is just for illustrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) + + +/* + * xSemaphoreAltTake() is an alternative version of xSemaphoreTake(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) + +/** + * semphr. h + *
xSemaphoreGive( xSemaphoreHandle xSemaphore )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+        {
+            // We would expect this call to fail because we cannot give
+            // a semaphore without first "taking" it!
+        }
+
+        // Obtain the semaphore - don't block if the semaphore is not
+        // immediately available.
+        if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
+        {
+            // We now have the semaphore and can access the shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource so can free the
+            // semaphore.
+            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+            {
+                // We would not expect this call to fail because we must have
+                // obtained the semaphore to get here.
+            }
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )
+ * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: +
+ xSemaphoreHandle xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.	
+        if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to 
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be 
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, it would be more likely that the calls
+			// to xSemaphoreGiveRecursive() would be called as a call stack
+			// unwound.  This is just for demonstrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) + +/* + * xSemaphoreAltGive() is an alternative version of xSemaphoreGive(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
+ xSemaphoreGiveFromISR( 
+                          xSemaphoreHandle xSemaphore, 
+                          signed portBASE_TYPE *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: +
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT	10
+ xSemaphoreHandle xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+    for( ;; )
+    {
+        // We want this task to run every 10 ticks of a timer.  The semaphore 
+        // was created before this task was started.
+
+        // Block waiting for the semaphore to become available.
+        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+        {
+            // It is time to execute.
+
+            // ...
+
+            // We have finished our task.  Return to the top of the loop where
+            // we will block on the semaphore until it is time to execute 
+            // again.  Note when using the semaphore for synchronisation with an
+			// ISR in this manner there is no need to 'give' the semaphore back.
+        }
+    }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static unsigned char ucLocalTickCount = 0;
+ static signed portBASE_TYPE xHigherPriorityTaskWoken;
+
+    // A timer tick has occurred.
+
+    // ... Do other time functions.
+
+    // Is it time for vATask () to run?
+	xHigherPriorityTaskWoken = pdFALSE;
+    ucLocalTickCount++;
+    if( ucLocalTickCount >= TICKS_TO_WAIT )
+    {
+        // Unblock the task by releasing the semaphore.
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+        // Reset the count so we release the semaphore again in 10 ticks time.
+        ucLocalTickCount = 0;
+    }
+
+    if( xHigherPriorityTaskWoken != pdFALSE )
+    {
+        // We can force a context switch here.  Context switching from an
+        // ISR uses port specific syntax.  Check the demo task for your port
+        // to find the syntax required.
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * semphr. h + *
+ xSemaphoreTakeFromISR( 
+                          xSemaphoreHandle xSemaphore, 
+                          signed portBASE_TYPE *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to take a semaphore from an ISR. The semaphore must have + * previously been created with a call to vSemaphoreCreateBinary() or + * xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR, however taking a semaphore from an ISR + * is not a common operation. It is likely to only be useful when taking a + * counting semaphore when an interrupt is obtaining an object from a resource + * pool (when the semaphore count indicates the number of resources available). + * + * @param xSemaphore A handle to the semaphore being taken. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully taken, otherwise + * pdFALSE + */ +#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
xSemaphoreHandle xSemaphoreCreateMutex( void )
+ * + * Macro that implements a mutex semaphore by using the existing queue + * mechanism. + * + * Mutexes created using this macro can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros should not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See vSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * xSemaphoreHandle. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex + * \ingroup Semaphores + */ +#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) + + +/** + * semphr. h + *
xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )
+ * + * Macro that implements a recursive mutex by using the existing queue + * mechanism. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros should not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See vSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * xSemaphoreHandle. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex + * \ingroup Semaphores + */ +#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) + +/** + * semphr. h + *
xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )
+ * + * Macro that creates a counting semaphore by using the existing + * queue mechanism. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: +
+ xSemaphoreHandle xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ xSemaphoreHandle xSemaphore = NULL;
+
+    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+    // The max value to which the semaphore can count should be 10, and the
+    // initial value assigned to the count should be 0.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.  
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) + +/** + * semphr. h + *
void vSemaphoreDelete( xSemaphoreHandle xSemaphore );
+ * + * Delete a semaphore. This function must be used with care. For example, + * do not delete a mutex type semaphore if the mutex is held by a task. + * + * @param xSemaphore A handle to the semaphore to be deleted. + * + * \defgroup vSemaphoreDelete vSemaphoreDelete + * \ingroup Semaphores + */ +#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) ( xSemaphore ) ) + +/** + * semphr.h + *
xTaskHandle xSemaphoreGetMutexHolder( xSemaphoreHandle xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + * Note: This Is is a good way of determining if the calling task is the mutex + * holder, but not a good way of determining the identity of the mutex holder as + * the holder may change between the function exiting and the returned value + * being tested. + */ +#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) + +#endif /* SEMAPHORE_H */ + + diff --git a/include/freertos/task.h b/include/freertos/task.h index 51e78857..aa234c45 100644 --- a/include/freertos/task.h +++ b/include/freertos/task.h @@ -1,1521 +1,1521 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - - -#ifndef INC_TASK_H -#define INC_TASK_H - -#ifndef INC_FREERTOS_H - #error "include FreeRTOS.h must appear in source files before include task.h" -#endif - -#include "list.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*----------------------------------------------------------- - * MACROS AND DEFINITIONS - *----------------------------------------------------------*/ - -#define tskKERNEL_VERSION_NUMBER "V7.5.2" - -/** - * task. h - * - * Type by which tasks are referenced. For example, a call to xTaskCreate - * returns (via a pointer parameter) an xTaskHandle variable that can then - * be used as a parameter to vTaskDelete to delete the task. - * - * \defgroup xTaskHandle xTaskHandle - * \ingroup Tasks - */ -typedef void * xTaskHandle; - -/* Task states returned by eTaskGetState. */ -typedef enum -{ - eRunning = 0, /* A task is querying the state of itself, so must be running. */ - eReady, /* The task being queried is in a read or pending ready list. */ - eBlocked, /* The task being queried is in the Blocked state. */ - eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ - eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */ -} eTaskState; - -/* - * Used internally only. - */ -typedef struct xTIME_OUT -{ - portBASE_TYPE xOverflowCount; - portTickType xTimeOnEntering; -} xTimeOutType; - -/* - * Defines the memory ranges allocated to the task when an MPU is used. - */ -typedef struct xMEMORY_REGION -{ - void *pvBaseAddress; - unsigned long ulLengthInBytes; - unsigned long ulParameters; -} xMemoryRegion; - -/* - * Parameters required to create an MPU protected task. - */ -typedef struct xTASK_PARAMTERS -{ - pdTASK_CODE pvTaskCode; - const signed char * const pcName; - unsigned short usStackDepth; - void *pvParameters; - unsigned portBASE_TYPE uxPriority; - portSTACK_TYPE *puxStackBuffer; - xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ]; -} xTaskParameters; - -/* Used with the uxTaskGetSystemState() function to return the state of each task -in the system. */ -typedef struct xTASK_STATUS -{ - xTaskHandle xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ - const signed char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ - unsigned portBASE_TYPE xTaskNumber; /* A number unique to the task. */ - eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ - unsigned portBASE_TYPE uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ - unsigned portBASE_TYPE uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ - unsigned long ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ - unsigned short usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ -} xTaskStatusType; - -/* Possible return values for eTaskConfirmSleepModeStatus(). */ -typedef enum -{ - eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ - eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ - eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ -} eSleepModeStatus; - - -/* - * Defines the priority used by the idle task. This must not be modified. - * - * \ingroup TaskUtils - */ -#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0U ) - -/** - * task. h - * - * Macro for forcing a context switch. - * - * \defgroup taskYIELD taskYIELD - * \ingroup SchedulerControl - */ -#define taskYIELD() portYIELD() - -/** - * task. h - * - * Macro to mark the start of a critical code region. Preemptive context - * switches cannot occur when in a critical region. - * - * NOTE: This may alter the stack (depending on the portable implementation) - * so must be used with care! - * - * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL - * \ingroup SchedulerControl - */ -#define taskENTER_CRITICAL() portENTER_CRITICAL() - -/** - * task. h - * - * Macro to mark the end of a critical code region. Preemptive context - * switches cannot occur when in a critical region. - * - * NOTE: This may alter the stack (depending on the portable implementation) - * so must be used with care! - * - * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL - * \ingroup SchedulerControl - */ -#define taskEXIT_CRITICAL() portEXIT_CRITICAL() - -/** - * task. h - * - * Macro to disable all maskable interrupts. - * - * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS - * \ingroup SchedulerControl - */ -#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() - -/** - * task. h - * - * Macro to enable microcontroller interrupts. - * - * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS - * \ingroup SchedulerControl - */ -#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() - -/* Definitions returned by xTaskGetSchedulerState(). */ -#define taskSCHEDULER_NOT_STARTED ( ( portBASE_TYPE ) 0 ) -#define taskSCHEDULER_RUNNING ( ( portBASE_TYPE ) 1 ) -#define taskSCHEDULER_SUSPENDED ( ( portBASE_TYPE ) 2 ) - -/*----------------------------------------------------------- - * TASK CREATION API - *----------------------------------------------------------*/ - -/** - * task. h - *
- portBASE_TYPE xTaskCreate(
-							  pdTASK_CODE pvTaskCode,
-							  const char * const pcName,
-							  unsigned short usStackDepth,
-							  void *pvParameters,
-							  unsigned portBASE_TYPE uxPriority,
-							  xTaskHandle *pvCreatedTask
-						  );
- * - * Create a new task and add it to the list of tasks that are ready to run. - * - * xTaskCreate() can only be used to create a task that has unrestricted - * access to the entire microcontroller memory map. Systems that include MPU - * support can alternatively create an MPU constrained task using - * xTaskCreateRestricted(). - * - * @param pvTaskCode Pointer to the task entry function. Tasks - * must be implemented to never return (i.e. continuous loop). - * - * @param pcName A descriptive name for the task. This is mainly used to - * facilitate debugging. Max length defined by tskMAX_TASK_NAME_LEN - default - * is 16. - * - * @param usStackDepth The size of the task stack specified as the number of - * variables the stack can hold - not the number of bytes. For example, if - * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes - * will be allocated for stack storage. - * - * @param pvParameters Pointer that will be used as the parameter for the task - * being created. - * - * @param uxPriority The priority at which the task should run. Systems that - * include MPU support can optionally create tasks in a privileged (system) - * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For - * example, to create a privileged task at priority 2 the uxPriority parameter - * should be set to ( 2 | portPRIVILEGE_BIT ). - * - * @param pvCreatedTask Used to pass back a handle by which the created task - * can be referenced. - * - * @return pdPASS if the task was successfully created and added to a ready - * list, otherwise an error code defined in the file errors. h - * - * Example usage: -
- // Task to be created.
- void vTaskCode( void * pvParameters )
- {
-	 for( ;; )
-	 {
-		 // Task code goes here.
-	 }
- }
-
- // Function that creates a task.
- void vOtherFunction( void )
- {
- static unsigned char ucParameterToPass;
- xTaskHandle xHandle;
-
-	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
-	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
-	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
-	 // the new task attempts to access it.
-	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
-
-	 // Use the handle to delete the task.
-	 vTaskDelete( xHandle );
- }
-   
- * \defgroup xTaskCreate xTaskCreate - * \ingroup Tasks - */ -#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) ) - -/** - * task. h - *
- portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle *pxCreatedTask );
- * - * xTaskCreateRestricted() should only be used in systems that include an MPU - * implementation. - * - * Create a new task and add it to the list of tasks that are ready to run. - * The function parameters define the memory regions and associated access - * permissions allocated to the task. - * - * @param pxTaskDefinition Pointer to a structure that contains a member - * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API - * documentation) plus an optional stack buffer and the memory region - * definitions. - * - * @param pxCreatedTask Used to pass back a handle by which the created task - * can be referenced. - * - * @return pdPASS if the task was successfully created and added to a ready - * list, otherwise an error code defined in the file errors. h - * - * Example usage: -
-// Create an xTaskParameters structure that defines the task to be created.
-static const xTaskParameters xCheckTaskParameters =
-{
-	vATask,		// pvTaskCode - the function that implements the task.
-	"ATask",	// pcName - just a text name for the task to assist debugging.
-	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
-	NULL,		// pvParameters - passed into the task function as the function parameters.
-	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
-	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
-
-	// xRegions - Allocate up to three separate memory regions for access by
-	// the task, with appropriate access permissions.  Different processors have
-	// different memory alignment requirements - refer to the FreeRTOS documentation
-	// for full information.
-	{
-		// Base address					Length	Parameters
-        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
-        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
-        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
-	}
-};
-
-int main( void )
-{
-xTaskHandle xHandle;
-
-	// Create a task from the const structure defined above.  The task handle
-	// is requested (the second parameter is not NULL) but in this case just for
-	// demonstration purposes as its not actually used.
-	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
-
-	// Start the scheduler.
-	vTaskStartScheduler();
-
-	// Will only get here if there was insufficient memory to create the idle
-	// task.
-	for( ;; );
-}
-   
- * \defgroup xTaskCreateRestricted xTaskCreateRestricted - * \ingroup Tasks - */ -#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) ) - -/** - * task. h - *
- void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );
- * - * Memory regions are assigned to a restricted task when the task is created by - * a call to xTaskCreateRestricted(). These regions can be redefined using - * vTaskAllocateMPURegions(). - * - * @param xTask The handle of the task being updated. - * - * @param xRegions A pointer to an xMemoryRegion structure that contains the - * new memory region definitions. - * - * Example usage: -
-// Define an array of xMemoryRegion structures that configures an MPU region
-// allowing read/write access for 1024 bytes starting at the beginning of the
-// ucOneKByte array.  The other two of the maximum 3 definable regions are
-// unused so set to zero.
-static const xMemoryRegion xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
-{
-	// Base address		Length		Parameters
-	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
-	{ 0,				0,			0 },
-	{ 0,				0,			0 }
-};
-
-void vATask( void *pvParameters )
-{
-	// This task was created such that it has access to certain regions of
-	// memory as defined by the MPU configuration.  At some point it is
-	// desired that these MPU regions are replaced with that defined in the
-	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
-	// for this purpose.  NULL is used as the task handle to indicate that this
-	// function should modify the MPU regions of the calling task.
-	vTaskAllocateMPURegions( NULL, xAltRegions );
-
-	// Now the task can continue its function, but from this point on can only
-	// access its stack and the ucOneKByte array (unless any other statically
-	// defined or shared regions have been declared elsewhere).
-}
-   
- * \defgroup xTaskCreateRestricted xTaskCreateRestricted - * \ingroup Tasks - */ -void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
void vTaskDelete( xTaskHandle xTask );
- * - * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. - * See the configuration section for more information. - * - * Remove a task from the RTOS real time kernels management. The task being - * deleted will be removed from all ready, blocked, suspended and event lists. - * - * NOTE: The idle task is responsible for freeing the kernel allocated - * memory from tasks that have been deleted. It is therefore important that - * the idle task is not starved of microcontroller processing time if your - * application makes any calls to vTaskDelete (). Memory allocated by the - * task code is not automatically freed, and should be freed before the task - * is deleted. - * - * See the demo application file death.c for sample code that utilises - * vTaskDelete (). - * - * @param xTask The handle of the task to be deleted. Passing NULL will - * cause the calling task to be deleted. - * - * Example usage: -
- void vOtherFunction( void )
- {
- xTaskHandle xHandle;
-
-	 // Create the task, storing the handle.
-	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
-
-	 // Use the handle to delete the task.
-	 vTaskDelete( xHandle );
- }
-   
- * \defgroup vTaskDelete vTaskDelete - * \ingroup Tasks - */ -void vTaskDelete( xTaskHandle xTaskToDelete ) PRIVILEGED_FUNCTION; - -/*----------------------------------------------------------- - * TASK CONTROL API - *----------------------------------------------------------*/ - -/** - * task. h - *
void vTaskDelay( portTickType xTicksToDelay );
- * - * Delay a task for a given number of ticks. The actual time that the - * task remains blocked depends on the tick rate. The constant - * portTICK_RATE_MS can be used to calculate real time from the tick - * rate - with the resolution of one tick period. - * - * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. - * See the configuration section for more information. - * - * - * vTaskDelay() specifies a time at which the task wishes to unblock relative to - * the time at which vTaskDelay() is called. For example, specifying a block - * period of 100 ticks will cause the task to unblock 100 ticks after - * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method - * of controlling the frequency of a cyclical task as the path taken through the - * code, as well as other task and interrupt activity, will effect the frequency - * at which vTaskDelay() gets called and therefore the time at which the task - * next executes. See vTaskDelayUntil() for an alternative API function designed - * to facilitate fixed frequency execution. It does this by specifying an - * absolute time (rather than a relative time) at which the calling task should - * unblock. - * - * @param xTicksToDelay The amount of time, in tick periods, that - * the calling task should block. - * - * Example usage: - - void vTaskFunction( void * pvParameters ) - { - void vTaskFunction( void * pvParameters ) - { - // Block for 500ms. - const portTickType xDelay = 500 / portTICK_RATE_MS; - - for( ;; ) - { - // Simply toggle the LED every 500ms, blocking between each toggle. - vToggleLED(); - vTaskDelay( xDelay ); - } - } - - * \defgroup vTaskDelay vTaskDelay - * \ingroup TaskCtrl - */ -void vTaskDelay( portTickType xTicksToDelay ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );
- * - * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. - * See the configuration section for more information. - * - * Delay a task until a specified time. This function can be used by cyclical - * tasks to ensure a constant execution frequency. - * - * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will - * cause a task to block for the specified number of ticks from the time vTaskDelay () is - * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed - * execution frequency as the time between a task starting to execute and that task - * calling vTaskDelay () may not be fixed [the task may take a different path though the - * code between calls, or may get interrupted or preempted a different number of times - * each time it executes]. - * - * Whereas vTaskDelay () specifies a wake time relative to the time at which the function - * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to - * unblock. - * - * The constant portTICK_RATE_MS can be used to calculate real time from the tick - * rate - with the resolution of one tick period. - * - * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the - * task was last unblocked. The variable must be initialised with the current time - * prior to its first use (see the example below). Following this the variable is - * automatically updated within vTaskDelayUntil (). - * - * @param xTimeIncrement The cycle time period. The task will be unblocked at - * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the - * same xTimeIncrement parameter value will cause the task to execute with - * a fixed interface period. - * - * Example usage: -
- // Perform an action every 10 ticks.
- void vTaskFunction( void * pvParameters )
- {
- portTickType xLastWakeTime;
- const portTickType xFrequency = 10;
-
-	 // Initialise the xLastWakeTime variable with the current time.
-	 xLastWakeTime = xTaskGetTickCount ();
-	 for( ;; )
-	 {
-		 // Wait for the next cycle.
-		 vTaskDelayUntil( &xLastWakeTime, xFrequency );
-
-		 // Perform action here.
-	 }
- }
-   
- * \defgroup vTaskDelayUntil vTaskDelayUntil - * \ingroup TaskCtrl - */ -void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle xTask );
- * - * INCLUDE_xTaskPriorityGet must be defined as 1 for this function to be available. - * See the configuration section for more information. - * - * Obtain the priority of any task. - * - * @param xTask Handle of the task to be queried. Passing a NULL - * handle results in the priority of the calling task being returned. - * - * @return The priority of xTask. - * - * Example usage: -
- void vAFunction( void )
- {
- xTaskHandle xHandle;
-
-	 // Create a task, storing the handle.
-	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
-
-	 // ...
-
-	 // Use the handle to obtain the priority of the created task.
-	 // It was created with tskIDLE_PRIORITY, but may have changed
-	 // it itself.
-	 if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
-	 {
-		 // The task has changed it's priority.
-	 }
-
-	 // ...
-
-	 // Is our priority higher than the created task?
-	 if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
-	 {
-		 // Our priority (obtained using NULL handle) is higher.
-	 }
- }
-   
- * \defgroup uxTaskPriorityGet uxTaskPriorityGet - * \ingroup TaskCtrl - */ -unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle xTask ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
eTaskState eTaskGetState( xTaskHandle xTask );
- * - * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. - * See the configuration section for more information. - * - * Obtain the state of any task. States are encoded by the eTaskState - * enumerated type. - * - * @param xTask Handle of the task to be queried. - * - * @return The state of xTask at the time the function was called. Note the - * state of the task might change between the function being called, and the - * functions return value being tested by the calling task. - */ -eTaskState eTaskGetState( xTaskHandle xTask ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
void vTaskPrioritySet( xTaskHandle xTask, unsigned portBASE_TYPE uxNewPriority );
- * - * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. - * See the configuration section for more information. - * - * Set the priority of any task. - * - * A context switch will occur before the function returns if the priority - * being set is higher than the currently executing task. - * - * @param xTask Handle to the task for which the priority is being set. - * Passing a NULL handle results in the priority of the calling task being set. - * - * @param uxNewPriority The priority to which the task will be set. - * - * Example usage: -
- void vAFunction( void )
- {
- xTaskHandle xHandle;
-
-	 // Create a task, storing the handle.
-	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
-
-	 // ...
-
-	 // Use the handle to raise the priority of the created task.
-	 vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
-
-	 // ...
-
-	 // Use a NULL handle to raise our priority to the same value.
-	 vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
- }
-   
- * \defgroup vTaskPrioritySet vTaskPrioritySet - * \ingroup TaskCtrl - */ -void vTaskPrioritySet( xTaskHandle xTask, unsigned portBASE_TYPE uxNewPriority ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
void vTaskSuspend( xTaskHandle xTaskToSuspend );
- * - * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. - * See the configuration section for more information. - * - * Suspend any task. When suspended a task will never get any microcontroller - * processing time, no matter what its priority. - * - * Calls to vTaskSuspend are not accumulative - - * i.e. calling vTaskSuspend () twice on the same task still only requires one - * call to vTaskResume () to ready the suspended task. - * - * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL - * handle will cause the calling task to be suspended. - * - * Example usage: -
- void vAFunction( void )
- {
- xTaskHandle xHandle;
-
-	 // Create a task, storing the handle.
-	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
-
-	 // ...
-
-	 // Use the handle to suspend the created task.
-	 vTaskSuspend( xHandle );
-
-	 // ...
-
-	 // The created task will not run during this period, unless
-	 // another task calls vTaskResume( xHandle ).
-
-	 //...
-
-
-	 // Suspend ourselves.
-	 vTaskSuspend( NULL );
-
-	 // We cannot get here unless another task calls vTaskResume
-	 // with our handle as the parameter.
- }
-   
- * \defgroup vTaskSuspend vTaskSuspend - * \ingroup TaskCtrl - */ -void vTaskSuspend( xTaskHandle xTaskToSuspend ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
void vTaskResume( xTaskHandle xTaskToResume );
- * - * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. - * See the configuration section for more information. - * - * Resumes a suspended task. - * - * A task that has been suspended by one of more calls to vTaskSuspend () - * will be made available for running again by a single call to - * vTaskResume (). - * - * @param xTaskToResume Handle to the task being readied. - * - * Example usage: -
- void vAFunction( void )
- {
- xTaskHandle xHandle;
-
-	 // Create a task, storing the handle.
-	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
-
-	 // ...
-
-	 // Use the handle to suspend the created task.
-	 vTaskSuspend( xHandle );
-
-	 // ...
-
-	 // The created task will not run during this period, unless
-	 // another task calls vTaskResume( xHandle ).
-
-	 //...
-
-
-	 // Resume the suspended task ourselves.
-	 vTaskResume( xHandle );
-
-	 // The created task will once again get microcontroller processing
-	 // time in accordance with it priority within the system.
- }
-   
- * \defgroup vTaskResume vTaskResume - * \ingroup TaskCtrl - */ -void vTaskResume( xTaskHandle xTaskToResume ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
void xTaskResumeFromISR( xTaskHandle xTaskToResume );
- * - * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be - * available. See the configuration section for more information. - * - * An implementation of vTaskResume() that can be called from within an ISR. - * - * A task that has been suspended by one of more calls to vTaskSuspend () - * will be made available for running again by a single call to - * xTaskResumeFromISR (). - * - * @param xTaskToResume Handle to the task being readied. - * - * \defgroup vTaskResumeFromISR vTaskResumeFromISR - * \ingroup TaskCtrl - */ -portBASE_TYPE xTaskResumeFromISR( xTaskHandle xTaskToResume ) PRIVILEGED_FUNCTION; - -/*----------------------------------------------------------- - * SCHEDULER CONTROL - *----------------------------------------------------------*/ - -/** - * task. h - *
void vTaskStartScheduler( void );
- * - * Starts the real time kernel tick processing. After calling the kernel - * has control over which tasks are executed and when. This function - * does not return until an executing task calls vTaskEndScheduler (). - * - * At least one task should be created via a call to xTaskCreate () - * before calling vTaskStartScheduler (). The idle task is created - * automatically when the first application task is created. - * - * See the demo application file main.c for an example of creating - * tasks and starting the kernel. - * - * Example usage: -
- void vAFunction( void )
- {
-	 // Create at least one task before starting the kernel.
-	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
-
-	 // Start the real time kernel with preemption.
-	 vTaskStartScheduler ();
-
-	 // Will not get here unless a task calls vTaskEndScheduler ()
- }
-   
- * - * \defgroup vTaskStartScheduler vTaskStartScheduler - * \ingroup SchedulerControl - */ -void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
void vTaskEndScheduler( void );
- * - * Stops the real time kernel tick. All created tasks will be automatically - * deleted and multitasking (either preemptive or cooperative) will - * stop. Execution then resumes from the point where vTaskStartScheduler () - * was called, as if vTaskStartScheduler () had just returned. - * - * See the demo application file main. c in the demo/PC directory for an - * example that uses vTaskEndScheduler (). - * - * vTaskEndScheduler () requires an exit function to be defined within the - * portable layer (see vPortEndScheduler () in port. c for the PC port). This - * performs hardware specific operations such as stopping the kernel tick. - * - * vTaskEndScheduler () will cause all of the resources allocated by the - * kernel to be freed - but will not free resources allocated by application - * tasks. - * - * Example usage: -
- void vTaskCode( void * pvParameters )
- {
-	 for( ;; )
-	 {
-		 // Task code goes here.
-
-		 // At some point we want to end the real time kernel processing
-		 // so call ...
-		 vTaskEndScheduler ();
-	 }
- }
-
- void vAFunction( void )
- {
-	 // Create at least one task before starting the kernel.
-	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
-
-	 // Start the real time kernel with preemption.
-	 vTaskStartScheduler ();
-
-	 // Will only get here when the vTaskCode () task has called
-	 // vTaskEndScheduler ().  When we get here we are back to single task
-	 // execution.
- }
-   
- * - * \defgroup vTaskEndScheduler vTaskEndScheduler - * \ingroup SchedulerControl - */ -void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
void vTaskSuspendAll( void );
- * - * Suspends all real time kernel activity while keeping interrupts (including the - * kernel tick) enabled. - * - * After calling vTaskSuspendAll () the calling task will continue to execute - * without risk of being swapped out until a call to xTaskResumeAll () has been - * made. - * - * API functions that have the potential to cause a context switch (for example, - * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler - * is suspended. - * - * Example usage: -
- void vTask1( void * pvParameters )
- {
-	 for( ;; )
-	 {
-		 // Task code goes here.
-
-		 // ...
-
-		 // At some point the task wants to perform a long operation during
-		 // which it does not want to get swapped out.  It cannot use
-		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
-		 // operation may cause interrupts to be missed - including the
-		 // ticks.
-
-		 // Prevent the real time kernel swapping out the task.
-		 vTaskSuspendAll ();
-
-		 // Perform the operation here.  There is no need to use critical
-		 // sections as we have all the microcontroller processing time.
-		 // During this time interrupts will still operate and the kernel
-		 // tick count will be maintained.
-
-		 // ...
-
-		 // The operation is complete.  Restart the kernel.
-		 xTaskResumeAll ();
-	 }
- }
-   
- * \defgroup vTaskSuspendAll vTaskSuspendAll - * \ingroup SchedulerControl - */ -void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
char xTaskResumeAll( void );
- * - * Resumes real time kernel activity following a call to vTaskSuspendAll (). - * After a call to vTaskSuspendAll () the kernel will take control of which - * task is executing at any time. - * - * @return If resuming the scheduler caused a context switch then pdTRUE is - * returned, otherwise pdFALSE is returned. - * - * Example usage: -
- void vTask1( void * pvParameters )
- {
-	 for( ;; )
-	 {
-		 // Task code goes here.
-
-		 // ...
-
-		 // At some point the task wants to perform a long operation during
-		 // which it does not want to get swapped out.  It cannot use
-		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
-		 // operation may cause interrupts to be missed - including the
-		 // ticks.
-
-		 // Prevent the real time kernel swapping out the task.
-		 vTaskSuspendAll ();
-
-		 // Perform the operation here.  There is no need to use critical
-		 // sections as we have all the microcontroller processing time.
-		 // During this time interrupts will still operate and the real
-		 // time kernel tick count will be maintained.
-
-		 // ...
-
-		 // The operation is complete.  Restart the kernel.  We want to force
-		 // a context switch - but there is no point if resuming the scheduler
-		 // caused a context switch already.
-		 if( !xTaskResumeAll () )
-		 {
-			  taskYIELD ();
-		 }
-	 }
- }
-   
- * \defgroup xTaskResumeAll xTaskResumeAll - * \ingroup SchedulerControl - */ -signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
signed portBASE_TYPE xTaskIsTaskSuspended( const xTaskHandle xTask );
- * - * Utility task that simply returns pdTRUE if the task referenced by xTask is - * currently in the Suspended state, or pdFALSE if the task referenced by xTask - * is in any other state. - * - */ -signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) PRIVILEGED_FUNCTION; - -/*----------------------------------------------------------- - * TASK UTILITIES - *----------------------------------------------------------*/ - -/** - * task. h - *
portTickType xTaskGetTickCount( void );
- * - * @return The count of ticks since vTaskStartScheduler was called. - * - * \defgroup xTaskGetTickCount xTaskGetTickCount - * \ingroup TaskUtils - */ -portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
portTickType xTaskGetTickCountFromISR( void );
- * - * @return The count of ticks since vTaskStartScheduler was called. - * - * This is a version of xTaskGetTickCount() that is safe to be called from an - * ISR - provided that portTickType is the natural word size of the - * microcontroller being used or interrupt nesting is either not supported or - * not being used. - * - * \defgroup xTaskGetTickCount xTaskGetTickCount - * \ingroup TaskUtils - */ -portTickType xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
unsigned short uxTaskGetNumberOfTasks( void );
- * - * @return The number of tasks that the real time kernel is currently managing. - * This includes all ready, blocked and suspended tasks. A task that - * has been deleted but not yet freed by the idle task will also be - * included in the count. - * - * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks - * \ingroup TaskUtils - */ -unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery );
- * - * @return The text (human readable) name of the task referenced by the handle - * xTaskToQueury. A task can query its own name by either passing in its own - * handle, or by setting xTaskToQuery to NULL. INCLUDE_pcTaskGetTaskName must be - * set to 1 in FreeRTOSConfig.h for pcTaskGetTaskName() to be available. - * - * \defgroup pcTaskGetTaskName pcTaskGetTaskName - * \ingroup TaskUtils - */ -signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery ); - -/** - * task.h - *
unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );
- * - * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for - * this function to be available. - * - * Returns the high water mark of the stack associated with xTask. That is, - * the minimum free stack space there has been (in words, so on a 32 bit machine - * a value of 1 means 4 bytes) since the task started. The smaller the returned - * number the closer the task has come to overflowing its stack. - * - * @param xTask Handle of the task associated with the stack to be checked. - * Set xTask to NULL to check the stack of the calling task. - * - * @return The smallest amount of free stack space there has been (in bytes) - * since the task referenced by xTask was created. - */ -unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) PRIVILEGED_FUNCTION; - -/* When using trace macros it is sometimes necessary to include tasks.h before -FreeRTOS.h. When this is done pdTASK_HOOK_CODE will not yet have been defined, -so the following two prototypes will cause a compilation error. This can be -fixed by simply guarding against the inclusion of these two prototypes unless -they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration -constant. */ -#ifdef configUSE_APPLICATION_TASK_TAG - #if configUSE_APPLICATION_TASK_TAG == 1 - /** - * task.h - *
void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
- * - * Sets pxHookFunction to be the task hook function used by the task xTask. - * Passing xTask as NULL has the effect of setting the calling tasks hook - * function. - */ - void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) PRIVILEGED_FUNCTION; - - /** - * task.h - *
void xTaskGetApplicationTaskTag( xTaskHandle xTask );
- * - * Returns the pxHookFunction value assigned to the task xTask. - */ - pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) PRIVILEGED_FUNCTION; - #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ -#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ - -/** - * task.h - *
portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
- * - * Calls the hook function associated with xTask. Passing xTask as NULL has - * the effect of calling the Running tasks (the calling task) hook function. - * - * pvParameter is passed to the hook function for the task to interpret as it - * wants. - */ -portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) PRIVILEGED_FUNCTION; - -/** - * xTaskGetIdleTaskHandle() is only available if - * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. - * - * Simply returns the handle of the idle task. It is not valid to call - * xTaskGetIdleTaskHandle() before the scheduler has been started. - */ -xTaskHandle xTaskGetIdleTaskHandle( void ); - -/** - * configUSE_TRACE_FACILITY must bet defined as 1 in FreeRTOSConfig.h for - * uxTaskGetSystemState() to be available. - * - * uxTaskGetSystemState() populates an xTaskStatusType structure for each task in - * the system. xTaskStatusType structures contain, among other things, members - * for the task handle, task name, task priority, task state, and total amount - * of run time consumed by the task. See the xTaskStatusType structure - * definition in this file for the full member list. - * - * NOTE: This function is intended for debugging use only as its use results in - * the scheduler remaining suspended for an extended period. - * - * @param pxTaskStatusArray A pointer to an array of xTaskStatusType structures. - * The array must contain at least one xTaskStatusType structure for each task - * that is under the control of the RTOS. The number of tasks under the control - * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. - * - * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray - * parameter. The size is specified as the number of indexes in the array, or - * the number of xTaskStatusType structures contained in the array, not by the - * number of bytes in the array. - * - * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in - * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the - * total run time (as defined by the run time stats clock, see - * http://www.freertos.org/rtos-run-time-stats.html) since the target booted. - * pulTotalRunTime can be set to NULL to omit the total run time information. - * - * @return The number of xTaskStatusType structures that were populated by - * uxTaskGetSystemState(). This should equal the number returned by the - * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed - * in the uxArraySize parameter was too small. - * - * Example usage: -
-    // This example demonstrates how a human readable table of run time stats
-	// information is generated from raw data provided by uxTaskGetSystemState().
-	// The human readable table is written to pcWriteBuffer
-	void vTaskGetRunTimeStats( signed char *pcWriteBuffer )
-	{
-	xTaskStatusType *pxTaskStatusArray;
-	volatile unsigned portBASE_TYPE uxArraySize, x;
-	unsigned long ulTotalRunTime, ulStatsAsPercentage;
-
-		// Make sure the write buffer does not contain a string.
-		*pcWriteBuffer = 0x00;
-
-		// Take a snapshot of the number of tasks in case it changes while this
-		// function is executing.
-		uxArraySize = uxCurrentNumberOfTasks();
-
-		// Allocate a xTaskStatusType structure for each task.  An array could be
-		// allocated statically at compile time.
-		pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( xTaskStatusType ) );
-
-		if( pxTaskStatusArray != NULL )
-		{
-			// Generate raw status information about each task.
-			uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
-
-			// For percentage calculations.
-			ulTotalRunTime /= 100UL;
-
-			// Avoid divide by zero errors.
-			if( ulTotalRunTime > 0 )
-			{
-				// For each populated position in the pxTaskStatusArray array,
-				// format the raw data as human readable ASCII data
-				for( x = 0; x < uxArraySize; x++ )
-				{
-					// What percentage of the total run time has the task used?
-					// This will always be rounded down to the nearest integer.
-					// ulTotalRunTimeDiv100 has already been divided by 100.
-					ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
-
-					if( ulStatsAsPercentage > 0UL )
-					{
-						sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
-					}
-					else
-					{
-						// If the percentage is zero here then the task has
-						// consumed less than 1% of the total run time.
-						sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
-					}
-
-					pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
-				}
-			}
-
-			// The array is no longer needed, free the memory it consumes.
-			vPortFree( pxTaskStatusArray );
-		}
-	}
-	
- */ -unsigned portBASE_TYPE uxTaskGetSystemState( xTaskStatusType *pxTaskStatusArray, unsigned portBASE_TYPE uxArraySize, unsigned long *pulTotalRunTime ); - -/** - * task. h - *
void vTaskList( char *pcWriteBuffer );
- * - * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must - * both be defined as 1 for this function to be available. See the - * configuration section of the FreeRTOS.org website for more information. - * - * NOTE 1: This function will disable interrupts for its duration. It is - * not intended for normal application runtime use but as a debug aid. - * - * Lists all the current tasks, along with their current state and stack - * usage high water mark. - * - * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or - * suspended ('S'). - * - * PLEASE NOTE: - * - * This function is provided for convenience only, and is used by many of the - * demo applications. Do not consider it to be part of the scheduler. - * - * vTaskList() calls uxTaskGetSystemState(), then formats part of the - * uxTaskGetSystemState() output into a human readable table that displays task - * names, states and stack usage. - * - * vTaskList() has a dependency on the sprintf() C library function that might - * bloat the code size, use a lot of stack, and provide different results on - * different platforms. An alternative, tiny, third party, and limited - * functionality implementation of sprintf() is provided in many of the - * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note - * printf-stdarg.c does not provide a full snprintf() implementation!). - * - * It is recommended that production systems call uxTaskGetSystemState() - * directly to get access to raw stats data, rather than indirectly through a - * call to vTaskList(). - * - * @param pcWriteBuffer A buffer into which the above mentioned details - * will be written, in ascii form. This buffer is assumed to be large - * enough to contain the generated report. Approximately 40 bytes per - * task should be sufficient. - * - * \defgroup vTaskList vTaskList - * \ingroup TaskUtils - */ -void vTaskList( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION; - -/** - * task. h - *
void vTaskGetRunTimeStats( char *pcWriteBuffer );
- * - * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS - * must both be defined as 1 for this function to be available. The application - * must also then provide definitions for - * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE - * to configure a peripheral timer/counter and return the timers current count - * value respectively. The counter should be at least 10 times the frequency of - * the tick count. - * - * NOTE 1: This function will disable interrupts for its duration. It is - * not intended for normal application runtime use but as a debug aid. - * - * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total - * accumulated execution time being stored for each task. The resolution - * of the accumulated time value depends on the frequency of the timer - * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. - * Calling vTaskGetRunTimeStats() writes the total execution time of each - * task into a buffer, both as an absolute count value and as a percentage - * of the total system execution time. - * - * NOTE 2: - * - * This function is provided for convenience only, and is used by many of the - * demo applications. Do not consider it to be part of the scheduler. - * - * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the - * uxTaskGetSystemState() output into a human readable table that displays the - * amount of time each task has spent in the Running state in both absolute and - * percentage terms. - * - * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function - * that might bloat the code size, use a lot of stack, and provide different - * results on different platforms. An alternative, tiny, third party, and - * limited functionality implementation of sprintf() is provided in many of the - * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note - * printf-stdarg.c does not provide a full snprintf() implementation!). - * - * It is recommended that production systems call uxTaskGetSystemState() directly - * to get access to raw stats data, rather than indirectly through a call to - * vTaskGetRunTimeStats(). - * - * @param pcWriteBuffer A buffer into which the execution times will be - * written, in ascii form. This buffer is assumed to be large enough to - * contain the generated report. Approximately 40 bytes per task should - * be sufficient. - * - * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats - * \ingroup TaskUtils - */ -void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION; - -/*----------------------------------------------------------- - * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES - *----------------------------------------------------------*/ - -/* - * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY - * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS - * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. - * - * Called from the real time kernel tick (either preemptive or cooperative), - * this increments the tick count and checks if any tasks that are blocked - * for a finite period required removing from a blocked list and placing on - * a ready list. If a non-zero value is returned then a context switch is - * required because either: - * + A task was removed from a blocked list because its timeout had expired, - * or - * + Time slicing is in use and there is a task of equal priority to the - * currently running task. - */ -portBASE_TYPE xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; - -/* - * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN - * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. - * - * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. - * - * Removes the calling task from the ready list and places it both - * on the list of tasks waiting for a particular event, and the - * list of delayed tasks. The task will be removed from both lists - * and replaced on the ready list should either the event occur (and - * there be no higher priority tasks waiting on the same event) or - * the delay period expires. - * - * @param pxEventList The list containing tasks that are blocked waiting - * for the event to occur. - * - * @param xTicksToWait The maximum amount of time that the task should wait - * for the event to occur. This is specified in kernel ticks,the constant - * portTICK_RATE_MS can be used to convert kernel ticks into a real time - * period. - */ -void vTaskPlaceOnEventList( xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; - -/* - * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN - * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. - * - * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. - * - * This function performs nearly the same function as vTaskPlaceOnEventList(). - * The difference being that this function does not permit tasks to block - * indefinitely, whereas vTaskPlaceOnEventList() does. - * - * @return pdTRUE if the task being removed has a higher priority than the task - * making the call, otherwise pdFALSE. - */ -void vTaskPlaceOnEventListRestricted( xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; - -/* - * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN - * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. - * - * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. - * - * Removes a task from both the specified event list and the list of blocked - * tasks, and places it on a ready queue. - * - * xTaskRemoveFromEventList () will be called if either an event occurs to - * unblock a task, or the block timeout period expires. - * - * @return pdTRUE if the task being removed has a higher priority than the task - * making the call, otherwise pdFALSE. - */ -signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) PRIVILEGED_FUNCTION; - -/* - * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY - * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS - * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. - * - * Sets the pointer to the current TCB to the TCB of the highest priority task - * that is ready to run. - */ -void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; - -/* - * Return the handle of the calling task. - */ -xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; - -/* - * Capture the current time status for future reference. - */ -void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) PRIVILEGED_FUNCTION; - -/* - * Compare the time status now with that previously captured to see if the - * timeout has expired. - */ -portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) PRIVILEGED_FUNCTION; - -/* - * Shortcut used by the queue implementation to prevent unnecessary call to - * taskYIELD(); - */ -void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; - -/* - * Returns the scheduler state as taskSCHEDULER_RUNNING, - * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. - */ -portBASE_TYPE xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; - -/* - * Raises the priority of the mutex holder to that of the calling task should - * the mutex holder have a priority less than the calling task. - */ -void vTaskPriorityInherit( xTaskHandle const pxMutexHolder ) PRIVILEGED_FUNCTION; - -/* - * Set the priority of a task back to its proper priority in the case that it - * inherited a higher priority while it was holding a semaphore. - */ -void vTaskPriorityDisinherit( xTaskHandle const pxMutexHolder ) PRIVILEGED_FUNCTION; - -/* - * Generic version of the task creation function which is in turn called by the - * xTaskCreate() and xTaskCreateRestricted() macros. - */ -signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION; - -/* - * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. - */ -unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask ); - -/* - * Set the uxTCBNumber of the task referenced by the xTask parameter to - * ucHandle. - */ -void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle ); - -/* - * If tickless mode is being used, or a low power mode is implemented, then - * the tick interrupt will not execute during idle periods. When this is the - * case, the tick count value maintained by the scheduler needs to be kept up - * to date with the actual execution time by being skipped forward by the by - * a time equal to the idle period. - */ -void vTaskStepTick( portTickType xTicksToJump ); - -portTickType prvGetExpectedIdleTime( void ); - -/* - * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port - * specific sleep function to determine if it is ok to proceed with the sleep, - * and if it is ok to proceed, if it is ok to sleep indefinitely. - * - * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only - * called with the scheduler suspended, not from within a critical section. It - * is therefore possible for an interrupt to request a context switch between - * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being - * entered. eTaskConfirmSleepModeStatus() should be called from a short - * critical section between the timer being stopped and the sleep mode being - * entered to ensure it is ok to proceed into the sleep mode. - */ -eSleepModeStatus eTaskConfirmSleepModeStatus( void ); - -#ifdef __cplusplus -} -#endif -#endif /* INC_TASK_H */ - - - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef INC_TASK_H +#define INC_TASK_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include task.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V7.5.2" + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an xTaskHandle variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \defgroup xTaskHandle xTaskHandle + * \ingroup Tasks + */ +typedef void * xTaskHandle; + +/* Task states returned by eTaskGetState. */ +typedef enum +{ + eRunning = 0, /* A task is querying the state of itself, so must be running. */ + eReady, /* The task being queried is in a read or pending ready list. */ + eBlocked, /* The task being queried is in the Blocked state. */ + eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ + eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */ +} eTaskState; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + portBASE_TYPE xOverflowCount; + portTickType xTimeOnEntering; +} xTimeOutType; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + unsigned long ulLengthInBytes; + unsigned long ulParameters; +} xMemoryRegion; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMTERS +{ + pdTASK_CODE pvTaskCode; + const signed char * const pcName; + unsigned short usStackDepth; + void *pvParameters; + unsigned portBASE_TYPE uxPriority; + portSTACK_TYPE *puxStackBuffer; + xMemoryRegion xRegions[ portNUM_CONFIGURABLE_REGIONS ]; +} xTaskParameters; + +/* Used with the uxTaskGetSystemState() function to return the state of each task +in the system. */ +typedef struct xTASK_STATUS +{ + xTaskHandle xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ + const signed char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ + unsigned portBASE_TYPE xTaskNumber; /* A number unique to the task. */ + eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ + unsigned portBASE_TYPE uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ + unsigned portBASE_TYPE uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ + unsigned long ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ + unsigned short usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ +} xTaskStatusType; + +/* Possible return values for eTaskConfirmSleepModeStatus(). */ +typedef enum +{ + eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ + eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ + eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ +} eSleepModeStatus; + + +/* + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( unsigned portBASE_TYPE ) 0U ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \defgroup taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() + +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). */ +#define taskSCHEDULER_NOT_STARTED ( ( portBASE_TYPE ) 0 ) +#define taskSCHEDULER_RUNNING ( ( portBASE_TYPE ) 1 ) +#define taskSCHEDULER_SUSPENDED ( ( portBASE_TYPE ) 2 ) + +/*----------------------------------------------------------- + * TASK CREATION API + *----------------------------------------------------------*/ + +/** + * task. h + *
+ portBASE_TYPE xTaskCreate(
+							  pdTASK_CODE pvTaskCode,
+							  const char * const pcName,
+							  unsigned short usStackDepth,
+							  void *pvParameters,
+							  unsigned portBASE_TYPE uxPriority,
+							  xTaskHandle *pvCreatedTask
+						  );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by tskMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pvCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file errors. h + * + * Example usage: +
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+	 }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static unsigned char ucParameterToPass;
+ xTaskHandle xHandle;
+
+	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+	 // the new task attempts to access it.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) ) + +/** + * task. h + *
+ portBASE_TYPE xTaskCreateRestricted( xTaskParameters *pxTaskDefinition, xTaskHandle *pxCreatedTask );
+ * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file errors. h + * + * Example usage: +
+// Create an xTaskParameters structure that defines the task to be created.
+static const xTaskParameters xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+};
+
+int main( void )
+{
+xTaskHandle xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) ) + +/** + * task. h + *
+ void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions );
+ * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an xMemoryRegion structure that contains the + * new memory region definitions. + * + * Example usage: +
+// Define an array of xMemoryRegion structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const xMemoryRegion xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{
+	// Base address		Length		Parameters
+	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
+	{ 0,				0,			0 },
+	{ 0,				0,			0 }
+};
+
+void vATask( void *pvParameters )
+{
+	// This task was created such that it has access to certain regions of
+	// memory as defined by the MPU configuration.  At some point it is
+	// desired that these MPU regions are replaced with that defined in the
+	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+	// for this purpose.  NULL is used as the task handle to indicate that this
+	// function should modify the MPU regions of the calling task.
+	vTaskAllocateMPURegions( NULL, xAltRegions );
+
+	// Now the task can continue its function, but from this point on can only
+	// access its stack and the ucOneKByte array (unless any other statically
+	// defined or shared regions have been declared elsewhere).
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const pxRegions ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelete( xTaskHandle xTask );
+ * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernels management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param xTask The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: +
+ void vOtherFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create the task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete( xTaskHandle xTaskToDelete ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK CONTROL API + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskDelay( portTickType xTicksToDelay );
+ * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_RATE_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a cyclical task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + + void vTaskFunction( void * pvParameters ) + { + void vTaskFunction( void * pvParameters ) + { + // Block for 500ms. + const portTickType xDelay = 500 / portTICK_RATE_MS; + + for( ;; ) + { + // Simply toggle the LED every 500ms, blocking between each toggle. + vToggleLED(); + vTaskDelay( xDelay ); + } + } + + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay( portTickType xTicksToDelay ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelayUntil( portTickType *pxPreviousWakeTime, portTickType xTimeIncrement );
+ * + * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by cyclical + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The constant portTICK_RATE_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within vTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * Example usage: +
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ portTickType xLastWakeTime;
+ const portTickType xFrequency = 10;
+
+	 // Initialise the xLastWakeTime variable with the current time.
+	 xLastWakeTime = xTaskGetTickCount ();
+	 for( ;; )
+	 {
+		 // Wait for the next cycle.
+		 vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+		 // Perform action here.
+	 }
+ }
+   
+ * \defgroup vTaskDelayUntil vTaskDelayUntil + * \ingroup TaskCtrl + */ +void vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle xTask );
+ * + * INCLUDE_xTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param xTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of xTask. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to obtain the priority of the created task.
+	 // It was created with tskIDLE_PRIORITY, but may have changed
+	 // it itself.
+	 if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+	 {
+		 // The task has changed it's priority.
+	 }
+
+	 // ...
+
+	 // Is our priority higher than the created task?
+	 if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+	 {
+		 // Our priority (obtained using NULL handle) is higher.
+	 }
+ }
+   
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
eTaskState eTaskGetState( xTaskHandle xTask );
+ * + * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the state of any task. States are encoded by the eTaskState + * enumerated type. + * + * @param xTask Handle of the task to be queried. + * + * @return The state of xTask at the time the function was called. Note the + * state of the task might change between the function being called, and the + * functions return value being tested by the calling task. + */ +eTaskState eTaskGetState( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskPrioritySet( xTaskHandle xTask, unsigned portBASE_TYPE uxNewPriority );
+ * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param xTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to raise the priority of the created task.
+	 vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+	 // ...
+
+	 // Use a NULL handle to raise our priority to the same value.
+	 vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+   
+ * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet( xTaskHandle xTask, unsigned portBASE_TYPE uxNewPriority ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspend( xTaskHandle xTaskToSuspend );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Suspend ourselves.
+	 vTaskSuspend( NULL );
+
+	 // We cannot get here unless another task calls vTaskResume
+	 // with our handle as the parameter.
+ }
+   
+ * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend( xTaskHandle xTaskToSuspend ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskResume( xTaskHandle xTaskToResume );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one of more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param xTaskToResume Handle to the task being readied. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ xTaskHandle xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Resume the suspended task ourselves.
+	 vTaskResume( xHandle );
+
+	 // The created task will once again get microcontroller processing
+	 // time in accordance with it priority within the system.
+ }
+   
+ * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume( xTaskHandle xTaskToResume ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void xTaskResumeFromISR( xTaskHandle xTaskToResume );
+ * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one of more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * @param xTaskToResume Handle to the task being readied. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +portBASE_TYPE xTaskResumeFromISR( xTaskHandle xTaskToResume ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER CONTROL + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskStartScheduler( void );
+ * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. This function + * does not return until an executing task calls vTaskEndScheduler (). + * + * At least one task should be created via a call to xTaskCreate () + * before calling vTaskStartScheduler (). The idle task is created + * automatically when the first application task is created. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: +
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+   
+ * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskEndScheduler( void );
+ * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: +
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // At some point we want to end the real time kernel processing
+		 // so call ...
+		 vTaskEndScheduler ();
+	 }
+ }
+
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will only get here when the vTaskCode () task has called
+	 // vTaskEndScheduler ().  When we get here we are back to single task
+	 // execution.
+ }
+   
+ * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspendAll( void );
+ * + * Suspends all real time kernel activity while keeping interrupts (including the + * kernel tick) enabled. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the kernel
+		 // tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.
+		 xTaskResumeAll ();
+	 }
+ }
+   
+ * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
char xTaskResumeAll( void );
+ * + * Resumes real time kernel activity following a call to vTaskSuspendAll (). + * After a call to vTaskSuspendAll () the kernel will take control of which + * task is executing at any time. + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the real
+		 // time kernel tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.  We want to force
+		 // a context switch - but there is no point if resuming the scheduler
+		 // caused a context switch already.
+		 if( !xTaskResumeAll () )
+		 {
+			  taskYIELD ();
+		 }
+	 }
+ }
+   
+ * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +signed portBASE_TYPE xTaskResumeAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
signed portBASE_TYPE xTaskIsTaskSuspended( const xTaskHandle xTask );
+ * + * Utility task that simply returns pdTRUE if the task referenced by xTask is + * currently in the Suspended state, or pdFALSE if the task referenced by xTask + * is in any other state. + * + */ +signed portBASE_TYPE xTaskIsTaskSuspended( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK UTILITIES + *----------------------------------------------------------*/ + +/** + * task. h + *
portTickType xTaskGetTickCount( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +portTickType xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
portTickType xTaskGetTickCountFromISR( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that portTickType is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +portTickType xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
unsigned short uxTaskGetNumberOfTasks( void );
+ * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +unsigned portBASE_TYPE uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery );
+ * + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQueury. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. INCLUDE_pcTaskGetTaskName must be + * set to 1 in FreeRTOSConfig.h for pcTaskGetTaskName() to be available. + * + * \defgroup pcTaskGetTaskName pcTaskGetTaskName + * \ingroup TaskUtils + */ +signed char *pcTaskGetTaskName( xTaskHandle xTaskToQuery ); + +/** + * task.h + *
unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in bytes) + * since the task referenced by xTask was created. + */ +unsigned portBASE_TYPE uxTaskGetStackHighWaterMark( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + +/* When using trace macros it is sometimes necessary to include tasks.h before +FreeRTOS.h. When this is done pdTASK_HOOK_CODE will not yet have been defined, +so the following two prototypes will cause a compilation error. This can be +fixed by simply guarding against the inclusion of these two prototypes unless +they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration +constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG + #if configUSE_APPLICATION_TASK_TAG == 1 + /** + * task.h + *
void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ + void vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTag( xTaskHandle xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. + */ + pdTASK_HOOK_CODE xTaskGetApplicationTaskTag( xTaskHandle xTask ) PRIVILEGED_FUNCTION; + #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +/** + * task.h + *
portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. + */ +portBASE_TYPE xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) PRIVILEGED_FUNCTION; + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task. It is not valid to call + * xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +xTaskHandle xTaskGetIdleTaskHandle( void ); + +/** + * configUSE_TRACE_FACILITY must bet defined as 1 in FreeRTOSConfig.h for + * uxTaskGetSystemState() to be available. + * + * uxTaskGetSystemState() populates an xTaskStatusType structure for each task in + * the system. xTaskStatusType structures contain, among other things, members + * for the task handle, task name, task priority, task state, and total amount + * of run time consumed by the task. See the xTaskStatusType structure + * definition in this file for the full member list. + * + * NOTE: This function is intended for debugging use only as its use results in + * the scheduler remaining suspended for an extended period. + * + * @param pxTaskStatusArray A pointer to an array of xTaskStatusType structures. + * The array must contain at least one xTaskStatusType structure for each task + * that is under the control of the RTOS. The number of tasks under the control + * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. + * + * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray + * parameter. The size is specified as the number of indexes in the array, or + * the number of xTaskStatusType structures contained in the array, not by the + * number of bytes in the array. + * + * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in + * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the + * total run time (as defined by the run time stats clock, see + * http://www.freertos.org/rtos-run-time-stats.html) since the target booted. + * pulTotalRunTime can be set to NULL to omit the total run time information. + * + * @return The number of xTaskStatusType structures that were populated by + * uxTaskGetSystemState(). This should equal the number returned by the + * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed + * in the uxArraySize parameter was too small. + * + * Example usage: +
+    // This example demonstrates how a human readable table of run time stats
+	// information is generated from raw data provided by uxTaskGetSystemState().
+	// The human readable table is written to pcWriteBuffer
+	void vTaskGetRunTimeStats( signed char *pcWriteBuffer )
+	{
+	xTaskStatusType *pxTaskStatusArray;
+	volatile unsigned portBASE_TYPE uxArraySize, x;
+	unsigned long ulTotalRunTime, ulStatsAsPercentage;
+
+		// Make sure the write buffer does not contain a string.
+		*pcWriteBuffer = 0x00;
+
+		// Take a snapshot of the number of tasks in case it changes while this
+		// function is executing.
+		uxArraySize = uxCurrentNumberOfTasks();
+
+		// Allocate a xTaskStatusType structure for each task.  An array could be
+		// allocated statically at compile time.
+		pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( xTaskStatusType ) );
+
+		if( pxTaskStatusArray != NULL )
+		{
+			// Generate raw status information about each task.
+			uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
+
+			// For percentage calculations.
+			ulTotalRunTime /= 100UL;
+
+			// Avoid divide by zero errors.
+			if( ulTotalRunTime > 0 )
+			{
+				// For each populated position in the pxTaskStatusArray array,
+				// format the raw data as human readable ASCII data
+				for( x = 0; x < uxArraySize; x++ )
+				{
+					// What percentage of the total run time has the task used?
+					// This will always be rounded down to the nearest integer.
+					// ulTotalRunTimeDiv100 has already been divided by 100.
+					ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
+
+					if( ulStatsAsPercentage > 0UL )
+					{
+						sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
+					}
+					else
+					{
+						// If the percentage is zero here then the task has
+						// consumed less than 1% of the total run time.
+						sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
+					}
+
+					pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
+				}
+			}
+
+			// The array is no longer needed, free the memory it consumes.
+			vPortFree( pxTaskStatusArray );
+		}
+	}
+	
+ */ +unsigned portBASE_TYPE uxTaskGetSystemState( xTaskStatusType *pxTaskStatusArray, unsigned portBASE_TYPE uxArraySize, unsigned long *pulTotalRunTime ); + +/** + * task. h + *
void vTaskList( char *pcWriteBuffer );
+ * + * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must + * both be defined as 1 for this function to be available. See the + * configuration section of the FreeRTOS.org website for more information. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays task + * names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that might + * bloat the code size, use a lot of stack, and provide different results on + * different platforms. An alternative, tiny, third party, and limited + * functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly through a + * call to vTaskList(). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ascii form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \defgroup vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskGetRunTimeStats( char *pcWriteBuffer );
+ * + * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS + * must both be defined as 1 for this function to be available. The application + * must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * NOTE 2: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays the + * amount of time each task has spent in the Running state in both absolute and + * percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function + * that might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, and + * limited functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() directly + * to get access to raw stats data, rather than indirectly through a call to + * vTaskGetRunTimeStats(). + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ascii form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( signed char *pcWriteBuffer ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + *----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. If a non-zero value is returned then a context switch is + * required because either: + * + A task was removed from a blocked list because its timeout had expired, + * or + * + Time slicing is in use and there is a task of equal priority to the + * currently running task. + */ +portBASE_TYPE xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks,the constant + * portTICK_RATE_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList( xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +void vTaskPlaceOnEventListRestricted( xList * const pxEventList, portTickType xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList () will be called if either an event occurs to + * unblock a task, or the block timeout period expires. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +signed portBASE_TYPE xTaskRemoveFromEventList( const xList * const pxEventList ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +/* + * Capture the current time status for future reference. + */ +void vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) PRIVILEGED_FUNCTION; + +/* + * Compare the time status now with that previously captured to see if the + * timeout has expired. + */ +portBASE_TYPE xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +portBASE_TYPE xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +void vTaskPriorityInherit( xTaskHandle const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +void vTaskPriorityDisinherit( xTaskHandle const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Generic version of the task creation function which is in turn called by the + * xTaskCreate() and xTaskCreateRestricted() macros. + */ +signed portBASE_TYPE xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) PRIVILEGED_FUNCTION; + +/* + * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. + */ +unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask ); + +/* + * Set the uxTCBNumber of the task referenced by the xTask parameter to + * ucHandle. + */ +void vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle ); + +/* + * If tickless mode is being used, or a low power mode is implemented, then + * the tick interrupt will not execute during idle periods. When this is the + * case, the tick count value maintained by the scheduler needs to be kept up + * to date with the actual execution time by being skipped forward by the by + * a time equal to the idle period. + */ +void vTaskStepTick( portTickType xTicksToJump ); + +portTickType prvGetExpectedIdleTime( void ); + +/* + * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port + * specific sleep function to determine if it is ok to proceed with the sleep, + * and if it is ok to proceed, if it is ok to sleep indefinitely. + * + * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only + * called with the scheduler suspended, not from within a critical section. It + * is therefore possible for an interrupt to request a context switch between + * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being + * entered. eTaskConfirmSleepModeStatus() should be called from a short + * critical section between the timer being stopped and the sleep mode being + * entered to ensure it is ok to proceed into the sleep mode. + */ +eSleepModeStatus eTaskConfirmSleepModeStatus( void ); + +#ifdef __cplusplus +} +#endif +#endif /* INC_TASK_H */ + + + diff --git a/include/freertos/timers.h b/include/freertos/timers.h index 5eb20330..04ad6905 100644 --- a/include/freertos/timers.h +++ b/include/freertos/timers.h @@ -1,959 +1,959 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - - -#ifndef TIMERS_H -#define TIMERS_H - -#ifndef INC_FREERTOS_H - #error "include FreeRTOS.h must appear in source files before include timers.h" -#endif - -/*lint -e537 This headers are only multiply included if the application code -happens to also be including task.h. */ -#include "task.h" -/*lint +e956 */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* IDs for commands that can be sent/received on the timer queue. These are to -be used solely through the macros that make up the public software timer API, -as defined below. */ -#define tmrCOMMAND_START ( ( portBASE_TYPE ) 0 ) -#define tmrCOMMAND_STOP ( ( portBASE_TYPE ) 1 ) -#define tmrCOMMAND_CHANGE_PERIOD ( ( portBASE_TYPE ) 2 ) -#define tmrCOMMAND_DELETE ( ( portBASE_TYPE ) 3 ) - -/*----------------------------------------------------------- - * MACROS AND DEFINITIONS - *----------------------------------------------------------*/ - - /** - * Type by which software timers are referenced. For example, a call to - * xTimerCreate() returns an xTimerHandle variable that can then be used to - * reference the subject timer in calls to other software timer API functions - * (for example, xTimerStart(), xTimerReset(), etc.). - */ -typedef void * xTimerHandle; - -/* Define the prototype to which timer callback functions must conform. */ -typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer ); - -/** - * xTimerHandle xTimerCreate( const signed char *pcTimerName, - * portTickType xTimerPeriodInTicks, - * unsigned portBASE_TYPE uxAutoReload, - * void * pvTimerID, - * tmrTIMER_CALLBACK pxCallbackFunction ); - * - * Creates a new software timer instance. This allocates the storage required - * by the new timer, initialises the new timers internal state, and returns a - * handle by which the new timer can be referenced. - * - * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), - * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and - * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the - * active state. - * - * @param pcTimerName A text name that is assigned to the timer. This is done - * purely to assist debugging. The kernel itself only ever references a timer by - * its handle, and never by its name. - * - * @param xTimerPeriodInTicks The timer period. The time is defined in tick periods so - * the constant portTICK_RATE_MS can be used to convert a time that has been - * specified in milliseconds. For example, if the timer must expire after 100 - * ticks, then xTimerPeriodInTicks should be set to 100. Alternatively, if the timer - * must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_RATE_MS ) - * provided configTICK_RATE_HZ is less than or equal to 1000. - * - * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will - * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. If - * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and - * enter the dormant state after it expires. - * - * @param pvTimerID An identifier that is assigned to the timer being created. - * Typically this would be used in the timer callback function to identify which - * timer expired when the same callback function is assigned to more than one - * timer. - * - * @param pxCallbackFunction The function to call when the timer expires. - * Callback functions must have the prototype defined by tmrTIMER_CALLBACK, - * which is "void vCallbackFunction( xTimerHandle xTimer );". - * - * @return If the timer is successfully create then a handle to the newly - * created timer is returned. If the timer cannot be created (because either - * there is insufficient FreeRTOS heap remaining to allocate the timer - * structures, or the timer period was set to 0) then 0 is returned. - * - * Example usage: - * @verbatim - * #define NUM_TIMERS 5 - * - * // An array to hold handles to the created timers. - * xTimerHandle xTimers[ NUM_TIMERS ]; - * - * // An array to hold a count of the number of times each timer expires. - * long lExpireCounters[ NUM_TIMERS ] = { 0 }; - * - * // Define a callback function that will be used by multiple timer instances. - * // The callback function does nothing but count the number of times the - * // associated timer expires, and stop the timer once the timer has expired - * // 10 times. - * void vTimerCallback( xTimerHandle pxTimer ) - * { - * long lArrayIndex; - * const long xMaxExpiryCountBeforeStopping = 10; - * - * // Optionally do something if the pxTimer parameter is NULL. - * configASSERT( pxTimer ); - * - * // Which timer expired? - * lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer ); - * - * // Increment the number of times that pxTimer has expired. - * lExpireCounters[ lArrayIndex ] += 1; - * - * // If the timer has expired 10 times then stop it from running. - * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) - * { - * // Do not use a block time if calling a timer API function from a - * // timer callback function, as doing so could cause a deadlock! - * xTimerStop( pxTimer, 0 ); - * } - * } - * - * void main( void ) - * { - * long x; - * - * // Create then start some timers. Starting the timers before the scheduler - * // has been started means the timers will start running immediately that - * // the scheduler starts. - * for( x = 0; x < NUM_TIMERS; x++ ) - * { - * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. - * ( 100 * x ), // The timer period in ticks. - * pdTRUE, // The timers will auto-reload themselves when they expire. - * ( void * ) x, // Assign each timer a unique id equal to its array index. - * vTimerCallback // Each timer calls the same callback when it expires. - * ); - * - * if( xTimers[ x ] == NULL ) - * { - * // The timer was not created. - * } - * else - * { - * // Start the timer. No block time is specified, and even if one was - * // it would be ignored because the scheduler has not yet been - * // started. - * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) - * { - * // The timer could not be set into the Active state. - * } - * } - * } - * - * // ... - * // Create tasks here. - * // ... - * - * // Starting the scheduler will start the timers running as they have already - * // been set into the active state. - * xTaskStartScheduler(); - * - * // Should not reach here. - * for( ;; ); - * } - * @endverbatim - */ -xTimerHandle xTimerCreate( const signed char * const pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION; - -/** - * void *pvTimerGetTimerID( xTimerHandle xTimer ); - * - * Returns the ID assigned to the timer. - * - * IDs are assigned to timers using the pvTimerID parameter of the call to - * xTimerCreated() that was used to create the timer. - * - * If the same callback function is assigned to multiple timers then the timer - * ID can be used within the callback function to identify which timer actually - * expired. - * - * @param xTimer The timer being queried. - * - * @return The ID assigned to the timer being queried. - * - * Example usage: - * - * See the xTimerCreate() API function example usage scenario. - */ -void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION; - -/** - * portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ); - * - * Queries a timer to see if it is active or dormant. - * - * A timer will be dormant if: - * 1) It has been created but not started, or - * 2) It is an expired on-shot timer that has not been restarted. - * - * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), - * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and - * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the - * active state. - * - * @param xTimer The timer being queried. - * - * @return pdFALSE will be returned if the timer is dormant. A value other than - * pdFALSE will be returned if the timer is active. - * - * Example usage: - * @verbatim - * // This function assumes xTimer has already been created. - * void vAFunction( xTimerHandle xTimer ) - * { - * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" - * { - * // xTimer is active, do something. - * } - * else - * { - * // xTimer is not active, do something else. - * } - * } - * @endverbatim - */ -portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION; - -/** - * xTimerGetTimerDaemonTaskHandle() is only available if - * INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h. - * - * Simply returns the handle of the timer service/daemon task. It it not valid - * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. - */ -xTaskHandle xTimerGetTimerDaemonTaskHandle( void ); - -/** - * portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime ); - * - * Timer functionality is provided by a timer service/daemon task. Many of the - * public FreeRTOS timer API functions send commands to the timer service task - * though a queue called the timer command queue. The timer command queue is - * private to the kernel itself and is not directly accessible to application - * code. The length of the timer command queue is set by the - * configTIMER_QUEUE_LENGTH configuration constant. - * - * xTimerStart() starts a timer that was previously created using the - * xTimerCreate() API function. If the timer had already been started and was - * already in the active state, then xTimerStart() has equivalent functionality - * to the xTimerReset() API function. - * - * Starting a timer ensures the timer is in the active state. If the timer - * is not stopped, deleted, or reset in the mean time, the callback function - * associated with the timer will get called 'n' ticks after xTimerStart() was - * called, where 'n' is the timers defined period. - * - * It is valid to call xTimerStart() before the scheduler has been started, but - * when this is done the timer will not actually start until the scheduler is - * started, and the timers expiry time will be relative to when the scheduler is - * started, not relative to when xTimerStart() was called. - * - * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() - * to be available. - * - * @param xTimer The handle of the timer being started/restarted. - * - * @param xBlockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the start command to be successfully - * sent to the timer command queue, should the queue already be full when - * xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called - * before the scheduler is started. - * - * @return pdFAIL will be returned if the start command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will - * be returned if the command was successfully sent to the timer command queue. - * When the command is actually processed will depend on the priority of the - * timer service/daemon task relative to other tasks in the system, although the - * timers expiry time is relative to when xTimerStart() is actually called. The - * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * - * Example usage: - * - * See the xTimerCreate() API function example usage scenario. - * - */ -#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) - -/** - * portBASE_TYPE xTimerStop( xTimerHandle xTimer, portTickType xBlockTime ); - * - * Timer functionality is provided by a timer service/daemon task. Many of the - * public FreeRTOS timer API functions send commands to the timer service task - * though a queue called the timer command queue. The timer command queue is - * private to the kernel itself and is not directly accessible to application - * code. The length of the timer command queue is set by the - * configTIMER_QUEUE_LENGTH configuration constant. - * - * xTimerStop() stops a timer that was previously started using either of the - * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), - * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. - * - * Stopping a timer ensures the timer is not in the active state. - * - * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() - * to be available. - * - * @param xTimer The handle of the timer being stopped. - * - * @param xBlockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the stop command to be successfully - * sent to the timer command queue, should the queue already be full when - * xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called - * before the scheduler is started. - * - * @return pdFAIL will be returned if the stop command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will - * be returned if the command was successfully sent to the timer command queue. - * When the command is actually processed will depend on the priority of the - * timer service/daemon task relative to other tasks in the system. The timer - * service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * - * Example usage: - * - * See the xTimerCreate() API function example usage scenario. - * - */ -#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) ) - -/** - * portBASE_TYPE xTimerChangePeriod( xTimerHandle xTimer, - * portTickType xNewPeriod, - * portTickType xBlockTime ); - * - * Timer functionality is provided by a timer service/daemon task. Many of the - * public FreeRTOS timer API functions send commands to the timer service task - * though a queue called the timer command queue. The timer command queue is - * private to the kernel itself and is not directly accessible to application - * code. The length of the timer command queue is set by the - * configTIMER_QUEUE_LENGTH configuration constant. - * - * xTimerChangePeriod() changes the period of a timer that was previously - * created using the xTimerCreate() API function. - * - * xTimerChangePeriod() can be called to change the period of an active or - * dormant state timer. - * - * The configUSE_TIMERS configuration constant must be set to 1 for - * xTimerChangePeriod() to be available. - * - * @param xTimer The handle of the timer that is having its period changed. - * - * @param xNewPeriod The new period for xTimer. Timer periods are specified in - * tick periods, so the constant portTICK_RATE_MS can be used to convert a time - * that has been specified in milliseconds. For example, if the timer must - * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, - * if the timer must expire after 500ms, then xNewPeriod can be set to - * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than - * or equal to 1000. - * - * @param xBlockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the change period command to be - * successfully sent to the timer command queue, should the queue already be - * full when xTimerChangePeriod() was called. xBlockTime is ignored if - * xTimerChangePeriod() is called before the scheduler is started. - * - * @return pdFAIL will be returned if the change period command could not be - * sent to the timer command queue even after xBlockTime ticks had passed. - * pdPASS will be returned if the command was successfully sent to the timer - * command queue. When the command is actually processed will depend on the - * priority of the timer service/daemon task relative to other tasks in the - * system. The timer service/daemon task priority is set by the - * configTIMER_TASK_PRIORITY configuration constant. - * - * Example usage: - * @verbatim - * // This function assumes xTimer has already been created. If the timer - * // referenced by xTimer is already active when it is called, then the timer - * // is deleted. If the timer referenced by xTimer is not active when it is - * // called, then the period of the timer is set to 500ms and the timer is - * // started. - * void vAFunction( xTimerHandle xTimer ) - * { - * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" - * { - * // xTimer is already active - delete it. - * xTimerDelete( xTimer ); - * } - * else - * { - * // xTimer is not active, change its period to 500ms. This will also - * // cause the timer to start. Block for a maximum of 100 ticks if the - * // change period command cannot immediately be sent to the timer - * // command queue. - * if( xTimerChangePeriod( xTimer, 500 / portTICK_RATE_MS, 100 ) == pdPASS ) - * { - * // The command was successfully sent. - * } - * else - * { - * // The command could not be sent, even after waiting for 100 ticks - * // to pass. Take appropriate action here. - * } - * } - * } - * @endverbatim - */ - #define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) ) - -/** - * portBASE_TYPE xTimerDelete( xTimerHandle xTimer, portTickType xBlockTime ); - * - * Timer functionality is provided by a timer service/daemon task. Many of the - * public FreeRTOS timer API functions send commands to the timer service task - * though a queue called the timer command queue. The timer command queue is - * private to the kernel itself and is not directly accessible to application - * code. The length of the timer command queue is set by the - * configTIMER_QUEUE_LENGTH configuration constant. - * - * xTimerDelete() deletes a timer that was previously created using the - * xTimerCreate() API function. - * - * The configUSE_TIMERS configuration constant must be set to 1 for - * xTimerDelete() to be available. - * - * @param xTimer The handle of the timer being deleted. - * - * @param xBlockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the delete command to be - * successfully sent to the timer command queue, should the queue already be - * full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete() - * is called before the scheduler is started. - * - * @return pdFAIL will be returned if the delete command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will - * be returned if the command was successfully sent to the timer command queue. - * When the command is actually processed will depend on the priority of the - * timer service/daemon task relative to other tasks in the system. The timer - * service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * - * Example usage: - * - * See the xTimerChangePeriod() API function example usage scenario. - */ -#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) ) - -/** - * portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType xBlockTime ); - * - * Timer functionality is provided by a timer service/daemon task. Many of the - * public FreeRTOS timer API functions send commands to the timer service task - * though a queue called the timer command queue. The timer command queue is - * private to the kernel itself and is not directly accessible to application - * code. The length of the timer command queue is set by the - * configTIMER_QUEUE_LENGTH configuration constant. - * - * xTimerReset() re-starts a timer that was previously created using the - * xTimerCreate() API function. If the timer had already been started and was - * already in the active state, then xTimerReset() will cause the timer to - * re-evaluate its expiry time so that it is relative to when xTimerReset() was - * called. If the timer was in the dormant state then xTimerReset() has - * equivalent functionality to the xTimerStart() API function. - * - * Resetting a timer ensures the timer is in the active state. If the timer - * is not stopped, deleted, or reset in the mean time, the callback function - * associated with the timer will get called 'n' ticks after xTimerReset() was - * called, where 'n' is the timers defined period. - * - * It is valid to call xTimerReset() before the scheduler has been started, but - * when this is done the timer will not actually start until the scheduler is - * started, and the timers expiry time will be relative to when the scheduler is - * started, not relative to when xTimerReset() was called. - * - * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() - * to be available. - * - * @param xTimer The handle of the timer being reset/started/restarted. - * - * @param xBlockTime Specifies the time, in ticks, that the calling task should - * be held in the Blocked state to wait for the reset command to be successfully - * sent to the timer command queue, should the queue already be full when - * xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called - * before the scheduler is started. - * - * @return pdFAIL will be returned if the reset command could not be sent to - * the timer command queue even after xBlockTime ticks had passed. pdPASS will - * be returned if the command was successfully sent to the timer command queue. - * When the command is actually processed will depend on the priority of the - * timer service/daemon task relative to other tasks in the system, although the - * timers expiry time is relative to when xTimerStart() is actually called. The - * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY - * configuration constant. - * - * Example usage: - * @verbatim - * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass - * // without a key being pressed, then the LCD back-light is switched off. In - * // this case, the timer is a one-shot timer. - * - * xTimerHandle xBacklightTimer = NULL; - * - * // The callback function assigned to the one-shot timer. In this case the - * // parameter is not used. - * void vBacklightTimerCallback( xTimerHandle pxTimer ) - * { - * // The timer expired, therefore 5 seconds must have passed since a key - * // was pressed. Switch off the LCD back-light. - * vSetBacklightState( BACKLIGHT_OFF ); - * } - * - * // The key press event handler. - * void vKeyPressEventHandler( char cKey ) - * { - * // Ensure the LCD back-light is on, then reset the timer that is - * // responsible for turning the back-light off after 5 seconds of - * // key inactivity. Wait 10 ticks for the command to be successfully sent - * // if it cannot be sent immediately. - * vSetBacklightState( BACKLIGHT_ON ); - * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) - * { - * // The reset command was not executed successfully. Take appropriate - * // action here. - * } - * - * // Perform the rest of the key processing here. - * } - * - * void main( void ) - * { - * long x; - * - * // Create then start the one-shot timer that is responsible for turning - * // the back-light off if no keys are pressed within a 5 second period. - * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. - * ( 5000 / portTICK_RATE_MS), // The timer period in ticks. - * pdFALSE, // The timer is a one-shot timer. - * 0, // The id is not used by the callback so can take any value. - * vBacklightTimerCallback // The callback function that switches the LCD back-light off. - * ); - * - * if( xBacklightTimer == NULL ) - * { - * // The timer was not created. - * } - * else - * { - * // Start the timer. No block time is specified, and even if one was - * // it would be ignored because the scheduler has not yet been - * // started. - * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) - * { - * // The timer could not be set into the Active state. - * } - * } - * - * // ... - * // Create tasks here. - * // ... - * - * // Starting the scheduler will start the timer running as it has already - * // been set into the active state. - * xTaskStartScheduler(); - * - * // Should not reach here. - * for( ;; ); - * } - * @endverbatim - */ -#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) - -/** - * portBASE_TYPE xTimerStartFromISR( xTimerHandle xTimer, - * portBASE_TYPE *pxHigherPriorityTaskWoken ); - * - * A version of xTimerStart() that can be called from an interrupt service - * routine. - * - * @param xTimer The handle of the timer being started/restarted. - * - * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most - * of its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling xTimerStartFromISR() writes a message to the timer - * command queue, so has the potential to transition the timer service/daemon - * task out of the Blocked state. If calling xTimerStartFromISR() causes the - * timer service/daemon task to leave the Blocked state, and the timer service/ - * daemon task has a priority equal to or greater than the currently executing - * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will - * get set to pdTRUE internally within the xTimerStartFromISR() function. If - * xTimerStartFromISR() sets this value to pdTRUE then a context switch should - * be performed before the interrupt exits. - * - * @return pdFAIL will be returned if the start command could not be sent to - * the timer command queue. pdPASS will be returned if the command was - * successfully sent to the timer command queue. When the command is actually - * processed will depend on the priority of the timer service/daemon task - * relative to other tasks in the system, although the timers expiry time is - * relative to when xTimerStartFromISR() is actually called. The timer service/daemon - * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. - * - * Example usage: - * @verbatim - * // This scenario assumes xBacklightTimer has already been created. When a - * // key is pressed, an LCD back-light is switched on. If 5 seconds pass - * // without a key being pressed, then the LCD back-light is switched off. In - * // this case, the timer is a one-shot timer, and unlike the example given for - * // the xTimerReset() function, the key press event handler is an interrupt - * // service routine. - * - * // The callback function assigned to the one-shot timer. In this case the - * // parameter is not used. - * void vBacklightTimerCallback( xTimerHandle pxTimer ) - * { - * // The timer expired, therefore 5 seconds must have passed since a key - * // was pressed. Switch off the LCD back-light. - * vSetBacklightState( BACKLIGHT_OFF ); - * } - * - * // The key press interrupt service routine. - * void vKeyPressEventInterruptHandler( void ) - * { - * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - * - * // Ensure the LCD back-light is on, then restart the timer that is - * // responsible for turning the back-light off after 5 seconds of - * // key inactivity. This is an interrupt service routine so can only - * // call FreeRTOS API functions that end in "FromISR". - * vSetBacklightState( BACKLIGHT_ON ); - * - * // xTimerStartFromISR() or xTimerResetFromISR() could be called here - * // as both cause the timer to re-calculate its expiry time. - * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was - * // declared (in this function). - * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) - * { - * // The start command was not executed successfully. Take appropriate - * // action here. - * } - * - * // Perform the rest of the key processing here. - * - * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch - * // should be performed. The syntax required to perform a context switch - * // from inside an ISR varies from port to port, and from compiler to - * // compiler. Inspect the demos for the port you are using to find the - * // actual syntax required. - * if( xHigherPriorityTaskWoken != pdFALSE ) - * { - * // Call the interrupt safe yield function here (actual function - * // depends on the FreeRTOS port being used. - * } - * } - * @endverbatim - */ -#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) - -/** - * portBASE_TYPE xTimerStopFromISR( xTimerHandle xTimer, - * portBASE_TYPE *pxHigherPriorityTaskWoken ); - * - * A version of xTimerStop() that can be called from an interrupt service - * routine. - * - * @param xTimer The handle of the timer being stopped. - * - * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most - * of its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling xTimerStopFromISR() writes a message to the timer - * command queue, so has the potential to transition the timer service/daemon - * task out of the Blocked state. If calling xTimerStopFromISR() causes the - * timer service/daemon task to leave the Blocked state, and the timer service/ - * daemon task has a priority equal to or greater than the currently executing - * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will - * get set to pdTRUE internally within the xTimerStopFromISR() function. If - * xTimerStopFromISR() sets this value to pdTRUE then a context switch should - * be performed before the interrupt exits. - * - * @return pdFAIL will be returned if the stop command could not be sent to - * the timer command queue. pdPASS will be returned if the command was - * successfully sent to the timer command queue. When the command is actually - * processed will depend on the priority of the timer service/daemon task - * relative to other tasks in the system. The timer service/daemon task - * priority is set by the configTIMER_TASK_PRIORITY configuration constant. - * - * Example usage: - * @verbatim - * // This scenario assumes xTimer has already been created and started. When - * // an interrupt occurs, the timer should be simply stopped. - * - * // The interrupt service routine that stops the timer. - * void vAnExampleInterruptServiceRoutine( void ) - * { - * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - * - * // The interrupt has occurred - simply stop the timer. - * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined - * // (within this function). As this is an interrupt service routine, only - * // FreeRTOS API functions that end in "FromISR" can be used. - * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) - * { - * // The stop command was not executed successfully. Take appropriate - * // action here. - * } - * - * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch - * // should be performed. The syntax required to perform a context switch - * // from inside an ISR varies from port to port, and from compiler to - * // compiler. Inspect the demos for the port you are using to find the - * // actual syntax required. - * if( xHigherPriorityTaskWoken != pdFALSE ) - * { - * // Call the interrupt safe yield function here (actual function - * // depends on the FreeRTOS port being used. - * } - * } - * @endverbatim - */ -#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U ) - -/** - * portBASE_TYPE xTimerChangePeriodFromISR( xTimerHandle xTimer, - * portTickType xNewPeriod, - * portBASE_TYPE *pxHigherPriorityTaskWoken ); - * - * A version of xTimerChangePeriod() that can be called from an interrupt - * service routine. - * - * @param xTimer The handle of the timer that is having its period changed. - * - * @param xNewPeriod The new period for xTimer. Timer periods are specified in - * tick periods, so the constant portTICK_RATE_MS can be used to convert a time - * that has been specified in milliseconds. For example, if the timer must - * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, - * if the timer must expire after 500ms, then xNewPeriod can be set to - * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than - * or equal to 1000. - * - * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most - * of its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling xTimerChangePeriodFromISR() writes a message to the - * timer command queue, so has the potential to transition the timer service/ - * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() - * causes the timer service/daemon task to leave the Blocked state, and the - * timer service/daemon task has a priority equal to or greater than the - * currently executing task (the task that was interrupted), then - * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the - * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets - * this value to pdTRUE then a context switch should be performed before the - * interrupt exits. - * - * @return pdFAIL will be returned if the command to change the timers period - * could not be sent to the timer command queue. pdPASS will be returned if the - * command was successfully sent to the timer command queue. When the command - * is actually processed will depend on the priority of the timer service/daemon - * task relative to other tasks in the system. The timer service/daemon task - * priority is set by the configTIMER_TASK_PRIORITY configuration constant. - * - * Example usage: - * @verbatim - * // This scenario assumes xTimer has already been created and started. When - * // an interrupt occurs, the period of xTimer should be changed to 500ms. - * - * // The interrupt service routine that changes the period of xTimer. - * void vAnExampleInterruptServiceRoutine( void ) - * { - * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - * - * // The interrupt has occurred - change the period of xTimer to 500ms. - * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined - * // (within this function). As this is an interrupt service routine, only - * // FreeRTOS API functions that end in "FromISR" can be used. - * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) - * { - * // The command to change the timers period was not executed - * // successfully. Take appropriate action here. - * } - * - * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch - * // should be performed. The syntax required to perform a context switch - * // from inside an ISR varies from port to port, and from compiler to - * // compiler. Inspect the demos for the port you are using to find the - * // actual syntax required. - * if( xHigherPriorityTaskWoken != pdFALSE ) - * { - * // Call the interrupt safe yield function here (actual function - * // depends on the FreeRTOS port being used. - * } - * } - * @endverbatim - */ -#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) - -/** - * portBASE_TYPE xTimerResetFromISR( xTimerHandle xTimer, - * portBASE_TYPE *pxHigherPriorityTaskWoken ); - * - * A version of xTimerReset() that can be called from an interrupt service - * routine. - * - * @param xTimer The handle of the timer that is to be started, reset, or - * restarted. - * - * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most - * of its time in the Blocked state, waiting for messages to arrive on the timer - * command queue. Calling xTimerResetFromISR() writes a message to the timer - * command queue, so has the potential to transition the timer service/daemon - * task out of the Blocked state. If calling xTimerResetFromISR() causes the - * timer service/daemon task to leave the Blocked state, and the timer service/ - * daemon task has a priority equal to or greater than the currently executing - * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will - * get set to pdTRUE internally within the xTimerResetFromISR() function. If - * xTimerResetFromISR() sets this value to pdTRUE then a context switch should - * be performed before the interrupt exits. - * - * @return pdFAIL will be returned if the reset command could not be sent to - * the timer command queue. pdPASS will be returned if the command was - * successfully sent to the timer command queue. When the command is actually - * processed will depend on the priority of the timer service/daemon task - * relative to other tasks in the system, although the timers expiry time is - * relative to when xTimerResetFromISR() is actually called. The timer service/daemon - * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. - * - * Example usage: - * @verbatim - * // This scenario assumes xBacklightTimer has already been created. When a - * // key is pressed, an LCD back-light is switched on. If 5 seconds pass - * // without a key being pressed, then the LCD back-light is switched off. In - * // this case, the timer is a one-shot timer, and unlike the example given for - * // the xTimerReset() function, the key press event handler is an interrupt - * // service routine. - * - * // The callback function assigned to the one-shot timer. In this case the - * // parameter is not used. - * void vBacklightTimerCallback( xTimerHandle pxTimer ) - * { - * // The timer expired, therefore 5 seconds must have passed since a key - * // was pressed. Switch off the LCD back-light. - * vSetBacklightState( BACKLIGHT_OFF ); - * } - * - * // The key press interrupt service routine. - * void vKeyPressEventInterruptHandler( void ) - * { - * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - * - * // Ensure the LCD back-light is on, then reset the timer that is - * // responsible for turning the back-light off after 5 seconds of - * // key inactivity. This is an interrupt service routine so can only - * // call FreeRTOS API functions that end in "FromISR". - * vSetBacklightState( BACKLIGHT_ON ); - * - * // xTimerStartFromISR() or xTimerResetFromISR() could be called here - * // as both cause the timer to re-calculate its expiry time. - * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was - * // declared (in this function). - * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) - * { - * // The reset command was not executed successfully. Take appropriate - * // action here. - * } - * - * // Perform the rest of the key processing here. - * - * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch - * // should be performed. The syntax required to perform a context switch - * // from inside an ISR varies from port to port, and from compiler to - * // compiler. Inspect the demos for the port you are using to find the - * // actual syntax required. - * if( xHigherPriorityTaskWoken != pdFALSE ) - * { - * // Call the interrupt safe yield function here (actual function - * // depends on the FreeRTOS port being used. - * } - * } - * @endverbatim - */ -#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) - -/* - * Functions beyond this part are not part of the public API and are intended - * for use by the kernel only. - */ -portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; -portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION; - -#ifdef __cplusplus -} -#endif -#endif /* TIMERS_H */ - - - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef TIMERS_H +#define TIMERS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include timers.h" +#endif + +/*lint -e537 This headers are only multiply included if the application code +happens to also be including task.h. */ +#include "task.h" +/*lint +e956 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* IDs for commands that can be sent/received on the timer queue. These are to +be used solely through the macros that make up the public software timer API, +as defined below. */ +#define tmrCOMMAND_START ( ( portBASE_TYPE ) 0 ) +#define tmrCOMMAND_STOP ( ( portBASE_TYPE ) 1 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( portBASE_TYPE ) 2 ) +#define tmrCOMMAND_DELETE ( ( portBASE_TYPE ) 3 ) + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + + /** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an xTimerHandle variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ +typedef void * xTimerHandle; + +/* Define the prototype to which timer callback functions must conform. */ +typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer ); + +/** + * xTimerHandle xTimerCreate( const signed char *pcTimerName, + * portTickType xTimerPeriodInTicks, + * unsigned portBASE_TYPE uxAutoReload, + * void * pvTimerID, + * tmrTIMER_CALLBACK pxCallbackFunction ); + * + * Creates a new software timer instance. This allocates the storage required + * by the new timer, initialises the new timers internal state, and returns a + * handle by which the new timer can be referenced. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer by + * its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick periods so + * the constant portTICK_RATE_MS can be used to convert a time that has been + * specified in milliseconds. For example, if the timer must expire after 100 + * ticks, then xTimerPeriodInTicks should be set to 100. Alternatively, if the timer + * must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_RATE_MS ) + * provided configTICK_RATE_HZ is less than or equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. If + * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by tmrTIMER_CALLBACK, + * which is "void vCallbackFunction( xTimerHandle xTimer );". + * + * @return If the timer is successfully create then a handle to the newly + * created timer is returned. If the timer cannot be created (because either + * there is insufficient FreeRTOS heap remaining to allocate the timer + * structures, or the timer period was set to 0) then 0 is returned. + * + * Example usage: + * @verbatim + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * xTimerHandle xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * long lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( xTimerHandle pxTimer ) + * { + * long lArrayIndex; + * const long xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * long x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * x ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * xTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +xTimerHandle xTimerCreate( const signed char * const pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION; + +/** + * void *pvTimerGetTimerID( xTimerHandle xTimer ); + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used within the callback function to identify which timer actually + * expired. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION; + +/** + * portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ); + * + * Queries a timer to see if it is active or dormant. + * + * A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired on-shot timer that has not been restarted. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. + * void vAFunction( xTimerHandle xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + * @endverbatim + */ +portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION; + +/** + * xTimerGetTimerDaemonTaskHandle() is only available if + * INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the timer service/daemon task. It it not valid + * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. + */ +xTaskHandle xTimerGetTimerDaemonTaskHandle( void ); + +/** + * portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * though a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStart() starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerStart() has equivalent functionality + * to the xTimerReset() API function. + * + * Starting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerStart() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerStart() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerStart() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() + * to be available. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param xBlockTime Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the start command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) + +/** + * portBASE_TYPE xTimerStop( xTimerHandle xTimer, portTickType xBlockTime ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * though a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStop() stops a timer that was previously started using either of the + * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), + * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. + * + * Stopping a timer ensures the timer is not in the active state. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() + * to be available. + * + * @param xTimer The handle of the timer being stopped. + * + * @param xBlockTime Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) ) + +/** + * portBASE_TYPE xTimerChangePeriod( xTimerHandle xTimer, + * portTickType xNewPeriod, + * portTickType xBlockTime ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * though a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerChangePeriod() changes the period of a timer that was previously + * created using the xTimerCreate() API function. + * + * xTimerChangePeriod() can be called to change the period of an active or + * dormant state timer. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerChangePeriod() to be available. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_RATE_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param xBlockTime Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerChangePeriod() was called. xBlockTime is ignored if + * xTimerChangePeriod() is called before the scheduler is started. + * + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xBlockTime ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. The timer service/daemon task priority is set by the + * configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. If the timer + * // referenced by xTimer is already active when it is called, then the timer + * // is deleted. If the timer referenced by xTimer is not active when it is + * // called, then the period of the timer is set to 500ms and the timer is + * // started. + * void vAFunction( xTimerHandle xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is already active - delete it. + * xTimerDelete( xTimer ); + * } + * else + * { + * // xTimer is not active, change its period to 500ms. This will also + * // cause the timer to start. Block for a maximum of 100 ticks if the + * // change period command cannot immediately be sent to the timer + * // command queue. + * if( xTimerChangePeriod( xTimer, 500 / portTICK_RATE_MS, 100 ) == pdPASS ) + * { + * // The command was successfully sent. + * } + * else + * { + * // The command could not be sent, even after waiting for 100 ticks + * // to pass. Take appropriate action here. + * } + * } + * } + * @endverbatim + */ + #define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) ) + +/** + * portBASE_TYPE xTimerDelete( xTimerHandle xTimer, portTickType xBlockTime ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * though a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerDelete() deletes a timer that was previously created using the + * xTimerCreate() API function. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerDelete() to be available. + * + * @param xTimer The handle of the timer being deleted. + * + * @param xBlockTime Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the delete command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete() + * is called before the scheduler is started. + * + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerChangePeriod() API function example usage scenario. + */ +#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) ) + +/** + * portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType xBlockTime ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * though a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerReset() re-starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerReset() will cause the timer to + * re-evaluate its expiry time so that it is relative to when xTimerReset() was + * called. If the timer was in the dormant state then xTimerReset() has + * equivalent functionality to the xTimerStart() API function. + * + * Resetting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerReset() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerReset() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerReset() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() + * to be available. + * + * @param xTimer The handle of the timer being reset/started/restarted. + * + * @param xBlockTime Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the reset command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue even after xBlockTime ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer. + * + * xTimerHandle xBacklightTimer = NULL; + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( xTimerHandle pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press event handler. + * void vKeyPressEventHandler( char cKey ) + * { + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. Wait 10 ticks for the command to be successfully sent + * // if it cannot be sent immediately. + * vSetBacklightState( BACKLIGHT_ON ); + * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * } + * + * void main( void ) + * { + * long x; + * + * // Create then start the one-shot timer that is responsible for turning + * // the back-light off if no keys are pressed within a 5 second period. + * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. + * ( 5000 / portTICK_RATE_MS), // The timer period in ticks. + * pdFALSE, // The timer is a one-shot timer. + * 0, // The id is not used by the callback so can take any value. + * vBacklightTimerCallback // The callback function that switches the LCD back-light off. + * ); + * + * if( xBacklightTimer == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timer running as it has already + * // been set into the active state. + * xTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) ) + +/** + * portBASE_TYPE xTimerStartFromISR( xTimerHandle xTimer, + * portBASE_TYPE *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStart() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStartFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStartFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStartFromISR() function. If + * xTimerStartFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerStartFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( xTimerHandle pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then restart the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The start command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used. + * } + * } + * @endverbatim + */ +#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * portBASE_TYPE xTimerStopFromISR( xTimerHandle xTimer, + * portBASE_TYPE *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStop() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being stopped. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStopFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStopFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStopFromISR() function. If + * xTimerStopFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the timer should be simply stopped. + * + * // The interrupt service routine that stops the timer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - simply stop the timer. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The stop command was not executed successfully. Take appropriate + * // action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used. + * } + * } + * @endverbatim + */ +#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * portBASE_TYPE xTimerChangePeriodFromISR( xTimerHandle xTimer, + * portTickType xNewPeriod, + * portBASE_TYPE *pxHigherPriorityTaskWoken ); + * + * A version of xTimerChangePeriod() that can be called from an interrupt + * service routine. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_RATE_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerChangePeriodFromISR() writes a message to the + * timer command queue, so has the potential to transition the timer service/ + * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() + * causes the timer service/daemon task to leave the Blocked state, and the + * timer service/daemon task has a priority equal to or greater than the + * currently executing task (the task that was interrupted), then + * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the + * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets + * this value to pdTRUE then a context switch should be performed before the + * interrupt exits. + * + * @return pdFAIL will be returned if the command to change the timers period + * could not be sent to the timer command queue. pdPASS will be returned if the + * command was successfully sent to the timer command queue. When the command + * is actually processed will depend on the priority of the timer service/daemon + * task relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the period of xTimer should be changed to 500ms. + * + * // The interrupt service routine that changes the period of xTimer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - change the period of xTimer to 500ms. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The command to change the timers period was not executed + * // successfully. Take appropriate action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used. + * } + * } + * @endverbatim + */ +#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * portBASE_TYPE xTimerResetFromISR( xTimerHandle xTimer, + * portBASE_TYPE *pxHigherPriorityTaskWoken ); + * + * A version of xTimerReset() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer that is to be started, reset, or + * restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerResetFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerResetFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerResetFromISR() function. If + * xTimerResetFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerResetFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( xTimerHandle pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used. + * } + * } + * @endverbatim + */ +#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; +portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif +#endif /* TIMERS_H */ + + + diff --git a/include/freertos/xtensa_context.h b/include/freertos/xtensa_context.h index 1ea12b9c..7ae4c4ea 100644 --- a/include/freertos/xtensa_context.h +++ b/include/freertos/xtensa_context.h @@ -1,278 +1,278 @@ -/******************************************************************************* -Copyright (c) 2006-2008 by Tensilica Inc. ALL RIGHTS RESERVED. -These coded instructions, statements, and computer programs are the -copyrighted works and confidential proprietary information of Tensilica Inc. -They may not be modified, copied, reproduced, distributed, or disclosed to -third parties in any manner, medium, or form, in whole or in part, without -the prior written consent of Tensilica Inc. --------------------------------------------------------------------------------- - - XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES - -This header contains definitions and macros for use primarily by Xtensa -RTOS assembly coded source files. It includes and uses the Xtensa hardware -abstraction layer (HAL) to deal with config specifics. It may also be -included in C source files. - -!! Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported. !! - -NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes. - -*******************************************************************************/ - -#ifndef XTENSA_CONTEXT_H -#define XTENSA_CONTEXT_H - -#ifdef __ASSEMBLER__ -#include -#endif - -#include -#include -#include - - -/* -Align a value up to nearest n-byte boundary, where n is a power of 2. -*/ -#define ALIGNUP(n, val) (((val) + (n)-1) & -(n)) - - -/******************************************************************************* - -INTERRUPT STACK FRAME FOR A THREAD OR NESTED INTERRUPT - -A stack frame of this structure is allocated for any interrupt or exception. -It goes on the current stack. If the RTOS has a system stack for handling -interrupts, every thread stack must allow space for just one interrupt stack -frame, then nested interrupt stack frames go on the system stack. - -The frame includes basic registers (explicit) and "extra" registers introduced -by user TIE or the use of the MAC16 option in the user's Xtensa config. -The frame size is minimized by omitting regs not applicable to user's config. - -For Windowed ABI, this stack frame includes the interruptee's base save area, -another base save area to manage gcc nested functions, and a little temporary -space to help manage the spilling of the register windows. - -*******************************************************************************/ - -#define XT_STK_EXIT 0x00 /* (offset 0) exit point for dispatch */ -#define XT_STK_PC 0x04 /* return address */ -#define XT_STK_PS 0x08 /* at level 1 PS.EXCM is set here */ -#define XT_STK_A0 0x0C -#define XT_STK_A1 0x10 /* stack ptr before interrupt */ -#define XT_STK_A2 0x14 -#define XT_STK_A3 0x18 -#define XT_STK_A4 0x1C -#define XT_STK_A5 0x20 -#define XT_STK_A6 0x24 -#define XT_STK_A7 0x28 -#define XT_STK_A8 0x2C -#define XT_STK_A9 0x30 -#define XT_STK_A10 0x34 -#define XT_STK_A11 0x38 -#define XT_STK_A12 0x3C /* Call0 callee-save */ -#define XT_STK_A13 0x40 /* Call0 callee-save */ -#define XT_STK_A14 0x44 /* Call0 callee-save */ -#define XT_STK_A15 0x48 /* Call0 callee-save */ -#define XT_STK_SAR 0x4C - -#if XCHAL_HAVE_LOOPS -#define XT_STK_LBEG 0x50 -#define XT_STK_LEND 0x54 -#define XT_STK_LCOUNT 0x58 -#define XT_STK_NEXT1 0x5C /* next unused offset */ -#else -#define XT_STK_NEXT1 0x50 /* next unused offset */ -#endif - /* there may be some unused space here */ -#if XCHAL_EXTRA_SA_SIZE != 0 -#define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) - -#define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE) -#else -#define XT_STK_NEXT2 XT_STK_NEXT1 -#endif - /* next unused offset */ - /* there may be some unused space here */ -#ifdef __XTENSA_CALL0_ABI__ -/* Call0 - no more stack frame needed */ -#define XT_STK_FRMSZ ALIGNUP(0x10, XT_STK_NEXT2) -#else -/* -Windowed - - Need some temp space for saving stuff during window spill. - Also add 16 bytes to skip over interruptee's base save area - and another 16 bytes in case of gcc nested functions: these - must be at physical top (logical base) of frame. -*/ -#define XT_STK_N_TMP 3 /* # of 4-byte temp. slots */ -#define XT_STK_TMP XT_STK_NEXT2 -#define XT_STK_NEXT3 XT_STK_TMP + (4 * XT_STK_N_TMP) -#define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT3) + 0x20) -#endif - - -/******************************************************************************* - -SOLICTED STACK FRAME FOR A THREAD - -A stack frame of this structure is allocated whenever a thread enters the -RTOS kernel intentionally (and synchronously) to submit to thread scheduling. -It goes on the current thread's stack. - -The solicted frame only includes registers that are required to be preserved -by the callee according to the compiler's ABI conventions, some space to save -the return address for returning to the caller, and the caller's PS register. - -For Windowed ABI, this stack frame includes the caller's base save area. - -Note on XT_SOL_EXIT field: - It is necessary to distinguish a solicited from an interrupt stack frame. - This field corresponds to XT_STK_EXIT in the interrupt stack frame and is - always at the same offset (0). It can be written with a code (usually 0) - to distinguish a solicted frame from an interrupt frame. An RTOS port may - opt to ignore this field if it has another way of distinguishing frames. - -*******************************************************************************/ - -#ifdef __XTENSA_CALL0_ABI__ - -/* Call0 ABI: room to save callee-save regs and return address. */ -#define XT_SOL_EXIT XT_STK_EXIT /* code indicates solicited frame */ -#define XT_SOL_PC 0x04 /* return address */ -#define XT_SOL_PS 0x08 -#define XT_SOL_NEXT 0x0c /* next unused offset */ - /* there may be some unused space here */ -#define XT_SOL_A12 ALIGNUP(0x10, XT_SOL_NEXT) -#define XT_SOL_A13 XT_SOL_A12 + 4 -#define XT_SOL_A14 XT_SOL_A13 + 4 -#define XT_SOL_A15 XT_SOL_A14 + 4 -#define XT_SOL_FRMSZ ALIGNUP(0x10, XT_SOL_A15) - -#else - -/* Windowed ABI: room to spill base-save area and save return address. */ -#define XT_SOL_EXIT XT_STK_EXIT /* code indicates solicited frame */ -#define XT_SOL_PC 0x04 /* return address (b30-31=callinc) */ -#define XT_SOL_PS 0x08 -#define XT_SOL_NEXT 0x0c /* next unused offset */ - /* there may be some unused space here */ -#define XT_SOL_A0 ALIGNUP(0x10, XT_SOL_NEXT) -#define XT_SOL_A1 XT_SOL_A0 + 4 -#define XT_SOL_A2 XT_SOL_A1 + 4 -#define XT_SOL_A3 XT_SOL_A2 + 4 -#define XT_SOL_FRMSZ ALIGNUP(0x10, XT_SOL_A3) - -#endif - - -/******************************************************************************* - -CO-PROCESSOR STATE SAVE AREA FOR A THREAD - -The RTOS must provide an area per thread to save the state of co-processors -when that thread does not have control. Co-processors are context-switched -lazily (on demand) only when a new thread uses a co-processor instruction, -otherwise a thread retains ownership of the co-processor even when it loses -control of the processor. An Xtensa co-processor exception is triggered when -any co-processor instruction is executed by a thread that is not the owner, -and the context switch of that co-processor is then peformed by the handler. -Ownership represents which thread's state is currently in the co-processor. - -Co-processors may not be used by interrupt or exception handlers. If an -co-processor instruction is executed by an interrupt or exception handler, -the co-processor exception handler will trigger a kernel panic and freeze. -This restriction is introduced to reduce the overhead of saving and restoring -co-processor state (which can be quite large) and in particular remove that -overhead from interrupt handlers. - -The co-processor state save area may be in any convenient per-thread location -such as in the thread control block or above the thread stack area. It need -not be in the interrupt stack frame since interrupts don't use co-processors. - -Along with the save area for each co-processor, two bitmasks with flags per -co-processor (laid out as in the CPENABLE reg) help manage context-switching -co-processors as efficiently as possible: - -XT_CPENABLE - The contents of a non-running thread's CPENABLE register. - It represents the co-processors owned (and whose state is still needed) - by the thread. When a thread is preempted, its CPENABLE is saved here. - When a thread solicits a context-swtich, its CPENABLE is cleared - the - compiler has saved the (caller-saved) co-proc state if it needs to. - When a non-running thread loses ownership of a CP, its bit is cleared. - When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg. - Avoids co-processor exceptions when no change of ownership is needed. - -XT_CPSTORED - A bitmask with the same layout as CPENABLE, a bit per co-processor. - Indicates whether the state of each co-processor is saved in the state - save area. When a thread enters the kernel, only the state of co-procs - still enabled in CPENABLE is saved. When the co-processor exception - handler assigns ownership of a co-processor to a thread, it restores - the saved state only if this bit is set, and clears this bit. - -*******************************************************************************/ - -#if XCHAL_CP_NUM > 0 -#define XT_CPENABLE 0 -#define XT_CPSTORED (XT_CPENABLE + 1) -#define XT_CP0_SA ALIGNUP(XCHAL_CP0_SA_ALIGN, XT_CPSTORED + 1) -#define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE) -#define XT_CP2_SA ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE) -#define XT_CP3_SA ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE) -#define XT_CP4_SA ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE) -#define XT_CP5_SA ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE) -#define XT_CP6_SA ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE) -#define XT_CP7_SA ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE) -#define XT_CP_SIZE ALIGNUP(4 , XT_CP7_SA + XCHAL_CP7_SA_SIZE) -#else -#define XT_CP_SIZE 0 -#endif - - -/******************************************************************************* - -MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN - -Convenient where the frame size requirements are the same for both ABIs. - ENTRY(sz), RET(sz) are for framed functions (have locals or make calls). - ENTRY0, RET0 are for frameless functions (no locals, no calls). -where size = size of stack frame in bytes (must be >0 and aligned to 16). -For framed functions the frame is created and the return address saved at -base of frame (Call0 ABI) or as determined by hardware (Windowed ABI). -For frameless functions, there is no frame and return address remains in a0. -Note: Because CPP macros expand to a single line, macros requiring multi-line -expansions are implemented as assembler macros. - -*******************************************************************************/ - -#ifdef __ASSEMBLER__ -#ifdef __XTENSA_CALL0_ABI__ - /* Call0 */ - #define ENTRY(sz) entry1 sz - .macro entry1 size=0x10 - addi sp, sp, -\size - s32i a0, sp, 0 - .endm - #define ENTRY0 - #define RET(sz) ret1 sz - .macro ret1 size=0x10 - l32i a0, sp, 0 - addi sp, sp, \size - ret - .endm - #define RET0 ret -#else - /* Windowed */ - #define ENTRY(sz) entry sp, sz - #define ENTRY0 entry sp, 0x10 - #define RET(sz) retw - #define RET0 retw -#endif -#endif - - -#endif /* XTENSA_CONTEXT_H */ +/******************************************************************************* +Copyright (c) 2006-2008 by Tensilica Inc. ALL RIGHTS RESERVED. +These coded instructions, statements, and computer programs are the +copyrighted works and confidential proprietary information of Tensilica Inc. +They may not be modified, copied, reproduced, distributed, or disclosed to +third parties in any manner, medium, or form, in whole or in part, without +the prior written consent of Tensilica Inc. +-------------------------------------------------------------------------------- + + XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES + +This header contains definitions and macros for use primarily by Xtensa +RTOS assembly coded source files. It includes and uses the Xtensa hardware +abstraction layer (HAL) to deal with config specifics. It may also be +included in C source files. + +!! Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported. !! + +NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes. + +*******************************************************************************/ + +#ifndef XTENSA_CONTEXT_H +#define XTENSA_CONTEXT_H + +#ifdef __ASSEMBLER__ +#include +#endif + +#include +#include +#include + + +/* +Align a value up to nearest n-byte boundary, where n is a power of 2. +*/ +#define ALIGNUP(n, val) (((val) + (n)-1) & -(n)) + + +/******************************************************************************* + +INTERRUPT STACK FRAME FOR A THREAD OR NESTED INTERRUPT + +A stack frame of this structure is allocated for any interrupt or exception. +It goes on the current stack. If the RTOS has a system stack for handling +interrupts, every thread stack must allow space for just one interrupt stack +frame, then nested interrupt stack frames go on the system stack. + +The frame includes basic registers (explicit) and "extra" registers introduced +by user TIE or the use of the MAC16 option in the user's Xtensa config. +The frame size is minimized by omitting regs not applicable to user's config. + +For Windowed ABI, this stack frame includes the interruptee's base save area, +another base save area to manage gcc nested functions, and a little temporary +space to help manage the spilling of the register windows. + +*******************************************************************************/ + +#define XT_STK_EXIT 0x00 /* (offset 0) exit point for dispatch */ +#define XT_STK_PC 0x04 /* return address */ +#define XT_STK_PS 0x08 /* at level 1 PS.EXCM is set here */ +#define XT_STK_A0 0x0C +#define XT_STK_A1 0x10 /* stack ptr before interrupt */ +#define XT_STK_A2 0x14 +#define XT_STK_A3 0x18 +#define XT_STK_A4 0x1C +#define XT_STK_A5 0x20 +#define XT_STK_A6 0x24 +#define XT_STK_A7 0x28 +#define XT_STK_A8 0x2C +#define XT_STK_A9 0x30 +#define XT_STK_A10 0x34 +#define XT_STK_A11 0x38 +#define XT_STK_A12 0x3C /* Call0 callee-save */ +#define XT_STK_A13 0x40 /* Call0 callee-save */ +#define XT_STK_A14 0x44 /* Call0 callee-save */ +#define XT_STK_A15 0x48 /* Call0 callee-save */ +#define XT_STK_SAR 0x4C + +#if XCHAL_HAVE_LOOPS +#define XT_STK_LBEG 0x50 +#define XT_STK_LEND 0x54 +#define XT_STK_LCOUNT 0x58 +#define XT_STK_NEXT1 0x5C /* next unused offset */ +#else +#define XT_STK_NEXT1 0x50 /* next unused offset */ +#endif + /* there may be some unused space here */ +#if XCHAL_EXTRA_SA_SIZE != 0 +#define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) + +#define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE) +#else +#define XT_STK_NEXT2 XT_STK_NEXT1 +#endif + /* next unused offset */ + /* there may be some unused space here */ +#ifdef __XTENSA_CALL0_ABI__ +/* Call0 - no more stack frame needed */ +#define XT_STK_FRMSZ ALIGNUP(0x10, XT_STK_NEXT2) +#else +/* +Windowed - + Need some temp space for saving stuff during window spill. + Also add 16 bytes to skip over interruptee's base save area + and another 16 bytes in case of gcc nested functions: these + must be at physical top (logical base) of frame. +*/ +#define XT_STK_N_TMP 3 /* # of 4-byte temp. slots */ +#define XT_STK_TMP XT_STK_NEXT2 +#define XT_STK_NEXT3 XT_STK_TMP + (4 * XT_STK_N_TMP) +#define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT3) + 0x20) +#endif + + +/******************************************************************************* + +SOLICTED STACK FRAME FOR A THREAD + +A stack frame of this structure is allocated whenever a thread enters the +RTOS kernel intentionally (and synchronously) to submit to thread scheduling. +It goes on the current thread's stack. + +The solicted frame only includes registers that are required to be preserved +by the callee according to the compiler's ABI conventions, some space to save +the return address for returning to the caller, and the caller's PS register. + +For Windowed ABI, this stack frame includes the caller's base save area. + +Note on XT_SOL_EXIT field: + It is necessary to distinguish a solicited from an interrupt stack frame. + This field corresponds to XT_STK_EXIT in the interrupt stack frame and is + always at the same offset (0). It can be written with a code (usually 0) + to distinguish a solicted frame from an interrupt frame. An RTOS port may + opt to ignore this field if it has another way of distinguishing frames. + +*******************************************************************************/ + +#ifdef __XTENSA_CALL0_ABI__ + +/* Call0 ABI: room to save callee-save regs and return address. */ +#define XT_SOL_EXIT XT_STK_EXIT /* code indicates solicited frame */ +#define XT_SOL_PC 0x04 /* return address */ +#define XT_SOL_PS 0x08 +#define XT_SOL_NEXT 0x0c /* next unused offset */ + /* there may be some unused space here */ +#define XT_SOL_A12 ALIGNUP(0x10, XT_SOL_NEXT) +#define XT_SOL_A13 XT_SOL_A12 + 4 +#define XT_SOL_A14 XT_SOL_A13 + 4 +#define XT_SOL_A15 XT_SOL_A14 + 4 +#define XT_SOL_FRMSZ ALIGNUP(0x10, XT_SOL_A15) + +#else + +/* Windowed ABI: room to spill base-save area and save return address. */ +#define XT_SOL_EXIT XT_STK_EXIT /* code indicates solicited frame */ +#define XT_SOL_PC 0x04 /* return address (b30-31=callinc) */ +#define XT_SOL_PS 0x08 +#define XT_SOL_NEXT 0x0c /* next unused offset */ + /* there may be some unused space here */ +#define XT_SOL_A0 ALIGNUP(0x10, XT_SOL_NEXT) +#define XT_SOL_A1 XT_SOL_A0 + 4 +#define XT_SOL_A2 XT_SOL_A1 + 4 +#define XT_SOL_A3 XT_SOL_A2 + 4 +#define XT_SOL_FRMSZ ALIGNUP(0x10, XT_SOL_A3) + +#endif + + +/******************************************************************************* + +CO-PROCESSOR STATE SAVE AREA FOR A THREAD + +The RTOS must provide an area per thread to save the state of co-processors +when that thread does not have control. Co-processors are context-switched +lazily (on demand) only when a new thread uses a co-processor instruction, +otherwise a thread retains ownership of the co-processor even when it loses +control of the processor. An Xtensa co-processor exception is triggered when +any co-processor instruction is executed by a thread that is not the owner, +and the context switch of that co-processor is then peformed by the handler. +Ownership represents which thread's state is currently in the co-processor. + +Co-processors may not be used by interrupt or exception handlers. If an +co-processor instruction is executed by an interrupt or exception handler, +the co-processor exception handler will trigger a kernel panic and freeze. +This restriction is introduced to reduce the overhead of saving and restoring +co-processor state (which can be quite large) and in particular remove that +overhead from interrupt handlers. + +The co-processor state save area may be in any convenient per-thread location +such as in the thread control block or above the thread stack area. It need +not be in the interrupt stack frame since interrupts don't use co-processors. + +Along with the save area for each co-processor, two bitmasks with flags per +co-processor (laid out as in the CPENABLE reg) help manage context-switching +co-processors as efficiently as possible: + +XT_CPENABLE + The contents of a non-running thread's CPENABLE register. + It represents the co-processors owned (and whose state is still needed) + by the thread. When a thread is preempted, its CPENABLE is saved here. + When a thread solicits a context-swtich, its CPENABLE is cleared - the + compiler has saved the (caller-saved) co-proc state if it needs to. + When a non-running thread loses ownership of a CP, its bit is cleared. + When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg. + Avoids co-processor exceptions when no change of ownership is needed. + +XT_CPSTORED + A bitmask with the same layout as CPENABLE, a bit per co-processor. + Indicates whether the state of each co-processor is saved in the state + save area. When a thread enters the kernel, only the state of co-procs + still enabled in CPENABLE is saved. When the co-processor exception + handler assigns ownership of a co-processor to a thread, it restores + the saved state only if this bit is set, and clears this bit. + +*******************************************************************************/ + +#if XCHAL_CP_NUM > 0 +#define XT_CPENABLE 0 +#define XT_CPSTORED (XT_CPENABLE + 1) +#define XT_CP0_SA ALIGNUP(XCHAL_CP0_SA_ALIGN, XT_CPSTORED + 1) +#define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE) +#define XT_CP2_SA ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE) +#define XT_CP3_SA ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE) +#define XT_CP4_SA ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE) +#define XT_CP5_SA ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE) +#define XT_CP6_SA ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE) +#define XT_CP7_SA ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE) +#define XT_CP_SIZE ALIGNUP(4 , XT_CP7_SA + XCHAL_CP7_SA_SIZE) +#else +#define XT_CP_SIZE 0 +#endif + + +/******************************************************************************* + +MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN + +Convenient where the frame size requirements are the same for both ABIs. + ENTRY(sz), RET(sz) are for framed functions (have locals or make calls). + ENTRY0, RET0 are for frameless functions (no locals, no calls). +where size = size of stack frame in bytes (must be >0 and aligned to 16). +For framed functions the frame is created and the return address saved at +base of frame (Call0 ABI) or as determined by hardware (Windowed ABI). +For frameless functions, there is no frame and return address remains in a0. +Note: Because CPP macros expand to a single line, macros requiring multi-line +expansions are implemented as assembler macros. + +*******************************************************************************/ + +#ifdef __ASSEMBLER__ +#ifdef __XTENSA_CALL0_ABI__ + /* Call0 */ + #define ENTRY(sz) entry1 sz + .macro entry1 size=0x10 + addi sp, sp, -\size + s32i a0, sp, 0 + .endm + #define ENTRY0 + #define RET(sz) ret1 sz + .macro ret1 size=0x10 + l32i a0, sp, 0 + addi sp, sp, \size + ret + .endm + #define RET0 ret +#else + /* Windowed */ + #define ENTRY(sz) entry sp, sz + #define ENTRY0 entry sp, 0x10 + #define RET(sz) retw + #define RET0 retw +#endif +#endif + + +#endif /* XTENSA_CONTEXT_H */ diff --git a/include/freertos/xtensa_rtos.h b/include/freertos/xtensa_rtos.h index f0702792..5ce3b76d 100644 --- a/include/freertos/xtensa_rtos.h +++ b/include/freertos/xtensa_rtos.h @@ -1,175 +1,175 @@ -/******************************************************************************* -Copyright (c) 2006-2009 by Tensilica Inc. ALL RIGHTS RESERVED. -These coded instructions, statements, and computer programs are the -copyrighted works and confidential proprietary information of Tensilica Inc. -They may not be modified, copied, reproduced, distributed, or disclosed to -third parties in any manner, medium, or form, in whole or in part, without -the prior written consent of Tensilica Inc. --------------------------------------------------------------------------------- - - RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES - -This header is the primary glue between generic Xtensa RTOS support -sources and a specific RTOS port for Xtensa. It contains definitions -and macros for use primarily by Xtensa assembly coded source files. - -Macros in this header map callouts from generic Xtensa files to specific -RTOS functions. It may also be included in C source files. - -Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa -architecture, using the Xtensa hardware abstraction layer (HAL) to deal -with configuration specifics. - -Should be included by all Xtensa generic and RTOS port-specific sources. - -*******************************************************************************/ - -#ifndef XTENSA_RTOS_H -#define XTENSA_RTOS_H - -#ifdef __ASSEMBLER__ -#include -#else -#include -#endif - -#include -#include -#include - -/* -Include any RTOS specific definitions that are needed by this header. -*/ - -#ifdef XCHAL_EXCM_LEVEL -#undef XCHAL_EXCM_LEVEL -#define XCHAL_EXCM_LEVEL 3 -#endif - -/* -Name of RTOS (for messages). -*/ -#define XT_RTOS_NAME FreeRTOS - -/* -Check some Xtensa configuration requirements and report error if not met. -Error messages can be customize to the RTOS port. -*/ - -#if !XCHAL_HAVE_XEA2 -#error "FreeRTOS/Xtensa requires XEA2 (exception architecture 2)." -#endif - - -/******************************************************************************* - -RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS. - -Define callout macros used in generic Xtensa code to interact with the RTOS. -The macros are simply the function names for use in calls from assembler code. -Some of these functions may call back to generic functions in xtensa_context.h . - -*******************************************************************************/ - -/* -Inform RTOS of entry into an interrupt handler that will affect it. -Allows RTOS to manage switch to any system stack and count nesting level. -Called after minimal context has been saved, with interrupts disabled. -RTOS port can call0 _xt_context_save to save the rest of the context. -May only be called from assembly code by the 'call0' instruction. -*/ -// void XT_RTOS_INT_ENTER(void) -#define XT_RTOS_INT_ENTER _xt_int_enter - -/* -Inform RTOS of completion of an interrupt handler, and give control to -RTOS to perform thread/task scheduling, switch back from any system stack -and restore the context, and return to the exit dispatcher saved in the -stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore -to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save, -leaving only a minimal part of the context to be restored by the exit -dispatcher. This function does not return to the place it was called from. -May only be called from assembly code by the 'call0' instruction. -*/ -// void XT_RTOS_INT_EXIT(void) -#define XT_RTOS_INT_EXIT _xt_int_exit - -/* -Inform RTOS of the occurrence of a tick timer interrupt. -If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined. -May be coded in or called from C or assembly, per ABI conventions. -RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro). -*/ -// void XT_RTOS_TIMER_INT(void) -#define XT_RTOS_TIMER_INT _xt_timer_int - -/* -Return in a15 the base address of the co-processor state save area for the -thread that triggered a co-processor exception, or 0 if no thread was running. -The state save area is structured as defined in xtensa_context.h and has size -XT_CP_SIZE. Co-processor instructions should only be used in thread code, never -in interrupt handlers or the RTOS kernel. May only be called from assembly code -and by the 'call0' instruction. A result of 0 indicates an unrecoverable error. -The implementation may use only a2-4, a15 (all other regs must be preserved). -*/ -// void* XT_RTOS_CP_STATE(void) - -/******************************************************************************* - -HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL. - -This Xtensa RTOS port provides hooks for dynamically installing exception -and interrupt handlers to facilitate automated testing where each test -case can install its own handler for user exceptions and each interrupt -priority (level). This consists of an array of function pointers indexed -by interrupt priority, with index 0 being the user exception handler hook. -Each entry in the array is initially 0, and may be replaced by a function -pointer of type XT_INTEXC_HOOK. A handler may be uninstalled by installing 0. - -The handler for low and medium priority obeys ABI conventions so may be coded -in C. For the exception handler, the cause is the contents of the EXCCAUSE -reg, and the result is -1 if handled, else the cause (still needs handling). -For interrupt handlers, the cause is a mask of pending enabled interrupts at -that level, and the result is the same mask with the bits for the handled -interrupts cleared (those not cleared still need handling). This allows a test -case to either pre-handle or override the default handling for the exception -or interrupt level (see xtensa_vectors.S). - -High priority handlers (including NMI) must be coded in assembly, are always -called by 'call0' regardless of ABI, must preserve all registers except a0, -and must not use or modify the interrupted stack. The hook argument 'cause' -is not passed and the result is ignored, so as not to burden the caller with -saving and restoring a2 (it assumes only one interrupt per level - see the -discussion in high priority interrupts in xtensa_vectors.S). The handler -therefore should be coded to prototype 'void h(void)' even though it plugs -into an array of handlers of prototype 'unsigned h(unsigned)'. - -To enable interrupt/exception hooks, compile the RTOS with '-DXT_INTEXC_HOOKS'. - -*******************************************************************************/ - -#define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI) - -#ifndef __ASSEMBLER__ -typedef unsigned (*XT_INTEXC_HOOK)(unsigned cause); -extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM]; -#endif - - -/******************************************************************************* - -CONVENIENCE INCLUSIONS. - -Ensures RTOS specific files need only include this one Xtensa-generic header. -These headers are included last so they can use the RTOS definitions above. - -*******************************************************************************/ - -#include "xtensa_context.h" - -#ifdef XT_RTOS_TIMER_INT -#include "xtensa_timer.h" -#endif - - -#endif /* XTENSA_RTOS_H */ +/******************************************************************************* +Copyright (c) 2006-2009 by Tensilica Inc. ALL RIGHTS RESERVED. +These coded instructions, statements, and computer programs are the +copyrighted works and confidential proprietary information of Tensilica Inc. +They may not be modified, copied, reproduced, distributed, or disclosed to +third parties in any manner, medium, or form, in whole or in part, without +the prior written consent of Tensilica Inc. +-------------------------------------------------------------------------------- + + RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES + +This header is the primary glue between generic Xtensa RTOS support +sources and a specific RTOS port for Xtensa. It contains definitions +and macros for use primarily by Xtensa assembly coded source files. + +Macros in this header map callouts from generic Xtensa files to specific +RTOS functions. It may also be included in C source files. + +Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa +architecture, using the Xtensa hardware abstraction layer (HAL) to deal +with configuration specifics. + +Should be included by all Xtensa generic and RTOS port-specific sources. + +*******************************************************************************/ + +#ifndef XTENSA_RTOS_H +#define XTENSA_RTOS_H + +#ifdef __ASSEMBLER__ +#include +#else +#include +#endif + +#include +#include +#include + +/* +Include any RTOS specific definitions that are needed by this header. +*/ + +#ifdef XCHAL_EXCM_LEVEL +#undef XCHAL_EXCM_LEVEL +#define XCHAL_EXCM_LEVEL 3 +#endif + +/* +Name of RTOS (for messages). +*/ +#define XT_RTOS_NAME FreeRTOS + +/* +Check some Xtensa configuration requirements and report error if not met. +Error messages can be customize to the RTOS port. +*/ + +#if !XCHAL_HAVE_XEA2 +#error "FreeRTOS/Xtensa requires XEA2 (exception architecture 2)." +#endif + + +/******************************************************************************* + +RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS. + +Define callout macros used in generic Xtensa code to interact with the RTOS. +The macros are simply the function names for use in calls from assembler code. +Some of these functions may call back to generic functions in xtensa_context.h . + +*******************************************************************************/ + +/* +Inform RTOS of entry into an interrupt handler that will affect it. +Allows RTOS to manage switch to any system stack and count nesting level. +Called after minimal context has been saved, with interrupts disabled. +RTOS port can call0 _xt_context_save to save the rest of the context. +May only be called from assembly code by the 'call0' instruction. +*/ +// void XT_RTOS_INT_ENTER(void) +#define XT_RTOS_INT_ENTER _xt_int_enter + +/* +Inform RTOS of completion of an interrupt handler, and give control to +RTOS to perform thread/task scheduling, switch back from any system stack +and restore the context, and return to the exit dispatcher saved in the +stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore +to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save, +leaving only a minimal part of the context to be restored by the exit +dispatcher. This function does not return to the place it was called from. +May only be called from assembly code by the 'call0' instruction. +*/ +// void XT_RTOS_INT_EXIT(void) +#define XT_RTOS_INT_EXIT _xt_int_exit + +/* +Inform RTOS of the occurrence of a tick timer interrupt. +If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined. +May be coded in or called from C or assembly, per ABI conventions. +RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro). +*/ +// void XT_RTOS_TIMER_INT(void) +#define XT_RTOS_TIMER_INT _xt_timer_int + +/* +Return in a15 the base address of the co-processor state save area for the +thread that triggered a co-processor exception, or 0 if no thread was running. +The state save area is structured as defined in xtensa_context.h and has size +XT_CP_SIZE. Co-processor instructions should only be used in thread code, never +in interrupt handlers or the RTOS kernel. May only be called from assembly code +and by the 'call0' instruction. A result of 0 indicates an unrecoverable error. +The implementation may use only a2-4, a15 (all other regs must be preserved). +*/ +// void* XT_RTOS_CP_STATE(void) + +/******************************************************************************* + +HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL. + +This Xtensa RTOS port provides hooks for dynamically installing exception +and interrupt handlers to facilitate automated testing where each test +case can install its own handler for user exceptions and each interrupt +priority (level). This consists of an array of function pointers indexed +by interrupt priority, with index 0 being the user exception handler hook. +Each entry in the array is initially 0, and may be replaced by a function +pointer of type XT_INTEXC_HOOK. A handler may be uninstalled by installing 0. + +The handler for low and medium priority obeys ABI conventions so may be coded +in C. For the exception handler, the cause is the contents of the EXCCAUSE +reg, and the result is -1 if handled, else the cause (still needs handling). +For interrupt handlers, the cause is a mask of pending enabled interrupts at +that level, and the result is the same mask with the bits for the handled +interrupts cleared (those not cleared still need handling). This allows a test +case to either pre-handle or override the default handling for the exception +or interrupt level (see xtensa_vectors.S). + +High priority handlers (including NMI) must be coded in assembly, are always +called by 'call0' regardless of ABI, must preserve all registers except a0, +and must not use or modify the interrupted stack. The hook argument 'cause' +is not passed and the result is ignored, so as not to burden the caller with +saving and restoring a2 (it assumes only one interrupt per level - see the +discussion in high priority interrupts in xtensa_vectors.S). The handler +therefore should be coded to prototype 'void h(void)' even though it plugs +into an array of handlers of prototype 'unsigned h(unsigned)'. + +To enable interrupt/exception hooks, compile the RTOS with '-DXT_INTEXC_HOOKS'. + +*******************************************************************************/ + +#define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI) + +#ifndef __ASSEMBLER__ +typedef unsigned (*XT_INTEXC_HOOK)(unsigned cause); +extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM]; +#endif + + +/******************************************************************************* + +CONVENIENCE INCLUSIONS. + +Ensures RTOS specific files need only include this one Xtensa-generic header. +These headers are included last so they can use the RTOS definitions above. + +*******************************************************************************/ + +#include "xtensa_context.h" + +#ifdef XT_RTOS_TIMER_INT +#include "xtensa_timer.h" +#endif + + +#endif /* XTENSA_RTOS_H */ diff --git a/include/freertos/xtensa_timer.h b/include/freertos/xtensa_timer.h index 70da91fe..1121543e 100644 --- a/include/freertos/xtensa_timer.h +++ b/include/freertos/xtensa_timer.h @@ -1,146 +1,146 @@ -/******************************************************************************* -Copyright (c) 2006-2009 by Tensilica Inc. ALL RIGHTS RESERVED. -These coded instructions, statements, and computer programs are the -copyrighted works and confidential proprietary information of Tensilica Inc. -They may not be modified, copied, reproduced, distributed, or disclosed to -third parties in any manner, medium, or form, in whole or in part, without -the prior written consent of Tensilica Inc. --------------------------------------------------------------------------------- - - XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY - -This header contains definitions and macros for use primarily by Xtensa -RTOS assembly coded source files. It includes and uses the Xtensa hardware -abstraction layer (HAL) to deal with config specifics. It may also be -included in C source files. - -User may edit to modify timer selection and to specify clock frequency and -tick duration to match timer interrupt to the real-time tick duration. - -If the RTOS has no timer interrupt, then there is no tick timer and the -clock frequency is irrelevant, so all of these macros are left undefined -and the Xtensa core configuration need not have a timer. - -*******************************************************************************/ - -#ifndef XTENSA_TIMER_H -#define XTENSA_TIMER_H - -#ifdef XT_RTOS_TIMER_INT /* skip all this stuff if no timer int */ - -#ifdef __ASSEMBLER__ -#include -#endif - -#include -#include - -#include "xtensa_rtos.h" /* in case this wasn't included directly */ - - -/* -Select timer to use for periodic tick, and determine its interrupt number -and priority. User may specify a timer by defining XT_TIMER_INDEX with -D, -in which case its validity is checked (it must exist in this core and must -not be on a high priority interrupt - an error will be reported in invalid). -Otherwise select the first low or medium priority interrupt timer available. -*/ -#ifndef XT_TIMER_INDEX - #if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL(XCHAL_TIMER3_INTERRUPT) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 3 - #endif - #endif - #if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 2 - #endif - #endif - #if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 1 - #endif - #endif - #if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED - #if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL - #undef XT_TIMER_INDEX - #define XT_TIMER_INDEX 0 - #endif - #endif -#endif -#ifndef XT_TIMER_INDEX - #error "There is no suitable timer in this Xtensa configuration." -#endif - -#define XT_CCOMPARE (CCOMPARE + XT_TIMER_INDEX) -#define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX) -#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM) -#define XT_TIMER_INTEN (1 << XT_TIMER_INTNUM) - -#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED - #error "The timer selected by XT_TIMER_INDEX does not exist in this core." -#elif XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL - #error "The timer interrupt cannot be high priority (use medium or low)." -#endif - -/* -Set processor clock frequency, used to determine clock divisor for timer tick. -User should BE SURE TO ADJUST THIS for the Xtensa platform being used. -If using a supported board via the board-independent API defined in xtbsp.h, -this may be left undefined and frequency and tick divisor will be computed -and cached during run-time initialization. - -NOTE ON SIMULATOR: -Under the Xtensa instruction set simulator, the frequency can only be estimated -because it depends on the speed of the host and the version of the simulator. -Also because it runs much slower than hardware, it is not possible to achieve -real-time performance for most applications under the simulator. A frequency -too low does not allow enough time between timer interrupts, starving threads. -To obtain a more convenient but non-real-time tick duration on the simulator, -compile with xt-xcc option "-DXT_SIMULATOR". -Adjust this frequency to taste (it's not real-time anyway!). -*/ -#if defined(XT_SIMULATOR) && !defined(XT_CLOCK_FREQ) -#define XT_CLOCK_FREQ 2000000 /* 2 MHz */ -#else -#ifdef XT_XT2000 /* deprecated */ -#define XT_CLOCK_FREQ 16500000 /* 16.5 MHz (XT2000 default) */ -#else -#define XT_CLOCK_FREQ 80000000 -#endif -#endif /* XT_SIMULATOR */ - -#if !defined(XT_CLOCK_FREQ) && !defined(XT_BOARD) - #error "XT_CLOCK_FREQ must be defined for the target platform." -#endif - -/* -Default number of timer "ticks" per second (default 100 for 10ms tick). -RTOS may define this in its own way (if applicable) in xtensa_rtos.h. -User may redefine this to an optimal value for the application, either by -editing this here or in xtensa_rtos.h, or compiling with xt-xcc option -"-DXT_TICKS_PER_SEC " where is a suitable number. -*/ -#ifndef XT_TICK_PER_SEC -#define XT_TICK_PER_SEC 100 /* 10 ms tick = 100 ticks per second */ -#endif - -/* -Derviation of clock divisor for timer tick and interrupt (one per tick). -*/ -#ifdef XT_CLOCK_FREQ -#define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC) -#else -#ifndef __ASSEMBLER__ -extern unsigned _xt_tick_divisor; -extern void _xt_tick_divisor_init(void); -#endif -#define XT_TICK_DIVISOR _xt_tick_divisor -#endif - -#endif /* XT_RTOS_TIMER_INT */ -#endif /* XTENSA_TIMER_H */ - +/******************************************************************************* +Copyright (c) 2006-2009 by Tensilica Inc. ALL RIGHTS RESERVED. +These coded instructions, statements, and computer programs are the +copyrighted works and confidential proprietary information of Tensilica Inc. +They may not be modified, copied, reproduced, distributed, or disclosed to +third parties in any manner, medium, or form, in whole or in part, without +the prior written consent of Tensilica Inc. +-------------------------------------------------------------------------------- + + XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY + +This header contains definitions and macros for use primarily by Xtensa +RTOS assembly coded source files. It includes and uses the Xtensa hardware +abstraction layer (HAL) to deal with config specifics. It may also be +included in C source files. + +User may edit to modify timer selection and to specify clock frequency and +tick duration to match timer interrupt to the real-time tick duration. + +If the RTOS has no timer interrupt, then there is no tick timer and the +clock frequency is irrelevant, so all of these macros are left undefined +and the Xtensa core configuration need not have a timer. + +*******************************************************************************/ + +#ifndef XTENSA_TIMER_H +#define XTENSA_TIMER_H + +#ifdef XT_RTOS_TIMER_INT /* skip all this stuff if no timer int */ + +#ifdef __ASSEMBLER__ +#include +#endif + +#include +#include + +#include "xtensa_rtos.h" /* in case this wasn't included directly */ + + +/* +Select timer to use for periodic tick, and determine its interrupt number +and priority. User may specify a timer by defining XT_TIMER_INDEX with -D, +in which case its validity is checked (it must exist in this core and must +not be on a high priority interrupt - an error will be reported in invalid). +Otherwise select the first low or medium priority interrupt timer available. +*/ +#ifndef XT_TIMER_INDEX + #if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED + #if XCHAL_INT_LEVEL(XCHAL_TIMER3_INTERRUPT) <= XCHAL_EXCM_LEVEL + #undef XT_TIMER_INDEX + #define XT_TIMER_INDEX 3 + #endif + #endif + #if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED + #if XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL + #undef XT_TIMER_INDEX + #define XT_TIMER_INDEX 2 + #endif + #endif + #if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED + #if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL + #undef XT_TIMER_INDEX + #define XT_TIMER_INDEX 1 + #endif + #endif + #if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED + #if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL + #undef XT_TIMER_INDEX + #define XT_TIMER_INDEX 0 + #endif + #endif +#endif +#ifndef XT_TIMER_INDEX + #error "There is no suitable timer in this Xtensa configuration." +#endif + +#define XT_CCOMPARE (CCOMPARE + XT_TIMER_INDEX) +#define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX) +#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM) +#define XT_TIMER_INTEN (1 << XT_TIMER_INTNUM) + +#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED + #error "The timer selected by XT_TIMER_INDEX does not exist in this core." +#elif XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL + #error "The timer interrupt cannot be high priority (use medium or low)." +#endif + +/* +Set processor clock frequency, used to determine clock divisor for timer tick. +User should BE SURE TO ADJUST THIS for the Xtensa platform being used. +If using a supported board via the board-independent API defined in xtbsp.h, +this may be left undefined and frequency and tick divisor will be computed +and cached during run-time initialization. + +NOTE ON SIMULATOR: +Under the Xtensa instruction set simulator, the frequency can only be estimated +because it depends on the speed of the host and the version of the simulator. +Also because it runs much slower than hardware, it is not possible to achieve +real-time performance for most applications under the simulator. A frequency +too low does not allow enough time between timer interrupts, starving threads. +To obtain a more convenient but non-real-time tick duration on the simulator, +compile with xt-xcc option "-DXT_SIMULATOR". +Adjust this frequency to taste (it's not real-time anyway!). +*/ +#if defined(XT_SIMULATOR) && !defined(XT_CLOCK_FREQ) +#define XT_CLOCK_FREQ 2000000 /* 2 MHz */ +#else +#ifdef XT_XT2000 /* deprecated */ +#define XT_CLOCK_FREQ 16500000 /* 16.5 MHz (XT2000 default) */ +#else +#define XT_CLOCK_FREQ 80000000 +#endif +#endif /* XT_SIMULATOR */ + +#if !defined(XT_CLOCK_FREQ) && !defined(XT_BOARD) + #error "XT_CLOCK_FREQ must be defined for the target platform." +#endif + +/* +Default number of timer "ticks" per second (default 100 for 10ms tick). +RTOS may define this in its own way (if applicable) in xtensa_rtos.h. +User may redefine this to an optimal value for the application, either by +editing this here or in xtensa_rtos.h, or compiling with xt-xcc option +"-DXT_TICKS_PER_SEC " where is a suitable number. +*/ +#ifndef XT_TICK_PER_SEC +#define XT_TICK_PER_SEC 100 /* 10 ms tick = 100 ticks per second */ +#endif + +/* +Derviation of clock divisor for timer tick and interrupt (one per tick). +*/ +#ifdef XT_CLOCK_FREQ +#define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC) +#else +#ifndef __ASSEMBLER__ +extern unsigned _xt_tick_divisor; +extern void _xt_tick_divisor_init(void); +#endif +#define XT_TICK_DIVISOR _xt_tick_divisor +#endif + +#endif /* XT_RTOS_TIMER_INT */ +#endif /* XTENSA_TIMER_H */ + diff --git a/include/lwip/apps/time.h b/include/lwip/apps/time.h old mode 100755 new mode 100644 diff --git a/include/lwip/arch/sys_arch.h b/include/lwip/arch/sys_arch.h index 18feef83..d132c1cf 100644 --- a/include/lwip/arch/sys_arch.h +++ b/include/lwip/arch/sys_arch.h @@ -1,54 +1,54 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef __SYS_ARCH_H__ -#define __SYS_ARCH_H__ - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" - -typedef xSemaphoreHandle sys_sem_t; -typedef xSemaphoreHandle sys_mutex_t; -typedef xQueueHandle sys_mbox_t; -typedef xTaskHandle sys_thread_t; - -#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) -#define sys_mbox_set_invalid( x ) ( ( *x ) = NULL ) -#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) -#define sys_sem_set_invalid( x ) ( ( *x ) = NULL ) - -#define LWIP_COMPAT_MUTEX 0 - -#endif /* __SYS_ARCH_H__ */ - +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __SYS_ARCH_H__ +#define __SYS_ARCH_H__ + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" + +typedef xSemaphoreHandle sys_sem_t; +typedef xSemaphoreHandle sys_mutex_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) +#define sys_mbox_set_invalid( x ) ( ( *x ) = NULL ) +#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE ) +#define sys_sem_set_invalid( x ) ( ( *x ) = NULL ) + +#define LWIP_COMPAT_MUTEX 0 + +#endif /* __SYS_ARCH_H__ */ + diff --git a/include/lwip/ipv4/lwip/autoip.h b/include/lwip/ipv4/lwip/autoip.h index 064ef87b..e62b72e8 100644 --- a/include/lwip/ipv4/lwip/autoip.h +++ b/include/lwip/ipv4/lwip/autoip.h @@ -1,118 +1,118 @@ -/** - * @file - * - * AutoIP Automatic LinkLocal IP Configuration - */ - -/* - * - * Copyright (c) 2007 Dominik Spies - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dominik Spies - * - * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform - * with RFC 3927. - * - * - * Please coordinate changes and requests with Dominik Spies - * - */ - -#ifndef __LWIP_AUTOIP_H__ -#define __LWIP_AUTOIP_H__ - -#include "lwip/opt.h" - -#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netif.h" -#include "lwip/udp.h" -#include "netif/etharp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* AutoIP Timing */ -#define AUTOIP_TMR_INTERVAL 100 -#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) - -/* RFC 3927 Constants */ -#define PROBE_WAIT 1 /* second (initial random delay) */ -#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ -#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ -#define PROBE_NUM 3 /* (number of probe packets) */ -#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ -#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ -#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ -#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ -#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ -#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ - -/* AutoIP client states */ -#define AUTOIP_STATE_OFF 0 -#define AUTOIP_STATE_PROBING 1 -#define AUTOIP_STATE_ANNOUNCING 2 -#define AUTOIP_STATE_BOUND 3 - -struct autoip -{ - ip_addr_t llipaddr; /* the currently selected, probed, announced or used LL IP-Address */ - u8_t state; /* current AutoIP state machine state */ - u8_t sent_num; /* sent number of probes or announces, dependent on state */ - u16_t ttw; /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */ - u8_t lastconflict; /* ticks until a conflict can be solved by defending */ - u8_t tried_llipaddr; /* total number of probed/used Link Local IP-Addresses */ -}; - - -#define autoip_init() /* Compatibility define, no init needed. */ - -/** Set a struct autoip allocated by the application to work with */ -void autoip_set_struct(struct netif *netif, struct autoip *autoip); - -/** Start AutoIP client */ -err_t autoip_start(struct netif *netif); - -/** Stop AutoIP client */ -err_t autoip_stop(struct netif *netif); - -/** Handles every incoming ARP Packet, called by etharp_arp_input */ -void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr); - -/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */ -void autoip_tmr(void); - -/** Handle a possible change in the network configuration */ -void autoip_network_changed(struct netif *netif); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_AUTOIP */ - -#endif /* __LWIP_AUTOIP_H__ */ +/** + * @file + * + * AutoIP Automatic LinkLocal IP Configuration + */ + +/* + * + * Copyright (c) 2007 Dominik Spies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dominik Spies + * + * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform + * with RFC 3927. + * + * + * Please coordinate changes and requests with Dominik Spies + * + */ + +#ifndef __LWIP_AUTOIP_H__ +#define __LWIP_AUTOIP_H__ + +#include "lwip/opt.h" + +#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" +#include "netif/etharp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* AutoIP Timing */ +#define AUTOIP_TMR_INTERVAL 100 +#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) + +/* RFC 3927 Constants */ +#define PROBE_WAIT 1 /* second (initial random delay) */ +#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ +#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ +#define PROBE_NUM 3 /* (number of probe packets) */ +#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ +#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ +#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ +#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ +#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ +#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ + +/* AutoIP client states */ +#define AUTOIP_STATE_OFF 0 +#define AUTOIP_STATE_PROBING 1 +#define AUTOIP_STATE_ANNOUNCING 2 +#define AUTOIP_STATE_BOUND 3 + +struct autoip +{ + ip_addr_t llipaddr; /* the currently selected, probed, announced or used LL IP-Address */ + u8_t state; /* current AutoIP state machine state */ + u8_t sent_num; /* sent number of probes or announces, dependent on state */ + u16_t ttw; /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */ + u8_t lastconflict; /* ticks until a conflict can be solved by defending */ + u8_t tried_llipaddr; /* total number of probed/used Link Local IP-Addresses */ +}; + + +#define autoip_init() /* Compatibility define, no init needed. */ + +/** Set a struct autoip allocated by the application to work with */ +void autoip_set_struct(struct netif *netif, struct autoip *autoip); + +/** Start AutoIP client */ +err_t autoip_start(struct netif *netif); + +/** Stop AutoIP client */ +err_t autoip_stop(struct netif *netif); + +/** Handles every incoming ARP Packet, called by etharp_arp_input */ +void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr); + +/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */ +void autoip_tmr(void); + +/** Handle a possible change in the network configuration */ +void autoip_network_changed(struct netif *netif); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_AUTOIP */ + +#endif /* __LWIP_AUTOIP_H__ */ diff --git a/include/lwip/ipv4/lwip/icmp.h b/include/lwip/ipv4/lwip/icmp.h index fb19a9e4..fa893b6b 100644 --- a/include/lwip/ipv4/lwip/icmp.h +++ b/include/lwip/ipv4/lwip/icmp.h @@ -1,125 +1,125 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_ICMP_H__ -#define __LWIP_ICMP_H__ - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" - -#if LWIP_IPV6 && LWIP_ICMP6 -#include "lwip/icmp6.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define ICMP_ER 0 /* echo reply */ -#define ICMP_DUR 3 /* destination unreachable */ -#define ICMP_SQ 4 /* source quench */ -#define ICMP_RD 5 /* redirect */ -#define ICMP_ECHO 8 /* echo */ -#define ICMP_TE 11 /* time exceeded */ -#define ICMP_PP 12 /* parameter problem */ -#define ICMP_TS 13 /* timestamp */ -#define ICMP_TSR 14 /* timestamp reply */ -#define ICMP_IRQ 15 /* information request */ -#define ICMP_IR 16 /* information reply */ - -enum icmp_dur_type { - ICMP_DUR_NET = 0, /* net unreachable */ - ICMP_DUR_HOST = 1, /* host unreachable */ - ICMP_DUR_PROTO = 2, /* protocol unreachable */ - ICMP_DUR_PORT = 3, /* port unreachable */ - ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ - ICMP_DUR_SR = 5 /* source route failed */ -}; - -enum icmp_te_type { - ICMP_TE_TTL = 0, /* time to live exceeded in transit */ - ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ -}; - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -/** This is the standard ICMP header only that the u32_t data - * is splitted to two u16_t like ICMP echo needs it. - * This header is also used for other ICMP types that do not - * use the data part. - */ -PACK_STRUCT_BEGIN -struct icmp_echo_hdr { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FIELD(u16_t seqno); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define ICMPH_TYPE(hdr) ((hdr)->type) -#define ICMPH_CODE(hdr) ((hdr)->code) - -/** Combines type and code to an u16_t */ -#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) -#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) - - -#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ - -void icmp_input(struct pbuf *p, struct netif *inp); -void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); -void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); - -#endif /* LWIP_ICMP */ - -#if (LWIP_IPV6 && LWIP_ICMP6) -#define icmp_port_unreach(isipv6, pbuf) ((isipv6) ? \ - icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) : \ - icmp_dest_unreach(pbuf, ICMP_DUR_PORT)) -#elif LWIP_ICMP -#define icmp_port_unreach(isipv6, pbuf) icmp_dest_unreach(pbuf, ICMP_DUR_PORT) -#else /* (LWIP_IPV6 && LWIP_ICMP6) || LWIP_ICMP*/ -#define icmp_port_unreach(isipv6, pbuf) -#endif /* (LWIP_IPV6 && LWIP_ICMP6) || LWIP_ICMP*/ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_ICMP_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ICMP_H__ +#define __LWIP_ICMP_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" + +#if LWIP_IPV6 && LWIP_ICMP6 +#include "lwip/icmp6.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define ICMP_ER 0 /* echo reply */ +#define ICMP_DUR 3 /* destination unreachable */ +#define ICMP_SQ 4 /* source quench */ +#define ICMP_RD 5 /* redirect */ +#define ICMP_ECHO 8 /* echo */ +#define ICMP_TE 11 /* time exceeded */ +#define ICMP_PP 12 /* parameter problem */ +#define ICMP_TS 13 /* timestamp */ +#define ICMP_TSR 14 /* timestamp reply */ +#define ICMP_IRQ 15 /* information request */ +#define ICMP_IR 16 /* information reply */ + +enum icmp_dur_type { + ICMP_DUR_NET = 0, /* net unreachable */ + ICMP_DUR_HOST = 1, /* host unreachable */ + ICMP_DUR_PROTO = 2, /* protocol unreachable */ + ICMP_DUR_PORT = 3, /* port unreachable */ + ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ + ICMP_DUR_SR = 5 /* source route failed */ +}; + +enum icmp_te_type { + ICMP_TE_TTL = 0, /* time to live exceeded in transit */ + ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ +}; + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +/** This is the standard ICMP header only that the u32_t data + * is splitted to two u16_t like ICMP echo needs it. + * This header is also used for other ICMP types that do not + * use the data part. + */ +PACK_STRUCT_BEGIN +struct icmp_echo_hdr { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u16_t seqno); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define ICMPH_TYPE(hdr) ((hdr)->type) +#define ICMPH_CODE(hdr) ((hdr)->code) + +/** Combines type and code to an u16_t */ +#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) +#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) + + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +void icmp_input(struct pbuf *p, struct netif *inp); +void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); +void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); + +#endif /* LWIP_ICMP */ + +#if (LWIP_IPV6 && LWIP_ICMP6) +#define icmp_port_unreach(isipv6, pbuf) ((isipv6) ? \ + icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) : \ + icmp_dest_unreach(pbuf, ICMP_DUR_PORT)) +#elif LWIP_ICMP +#define icmp_port_unreach(isipv6, pbuf) icmp_dest_unreach(pbuf, ICMP_DUR_PORT) +#else /* (LWIP_IPV6 && LWIP_ICMP6) || LWIP_ICMP*/ +#define icmp_port_unreach(isipv6, pbuf) +#endif /* (LWIP_IPV6 && LWIP_ICMP6) || LWIP_ICMP*/ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ICMP_H__ */ diff --git a/include/lwip/ipv4/lwip/igmp.h b/include/lwip/ipv4/lwip/igmp.h index 7bb18ea0..8aabac24 100644 --- a/include/lwip/ipv4/lwip/igmp.h +++ b/include/lwip/ipv4/lwip/igmp.h @@ -1,106 +1,106 @@ -/* - * Copyright (c) 2002 CITEL Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is a contribution to the lwIP TCP/IP stack. - * The Swedish Institute of Computer Science and Adam Dunkels - * are specifically granted permission to redistribute this - * source code. -*/ - -#ifndef __LWIP_IGMP_H__ -#define __LWIP_IGMP_H__ - -#include "lwip/opt.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/pbuf.h" - -#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* IGMP timer */ -#define IGMP_TMR_INTERVAL 100 /* Milliseconds */ -#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL) -#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL) - -/* MAC Filter Actions, these are passed to a netif's - * igmp_mac_filter callback function. */ -#define IGMP_DEL_MAC_FILTER 0 -#define IGMP_ADD_MAC_FILTER 1 - - -/** - * igmp group structure - there is - * a list of groups for each interface - * these should really be linked from the interface, but - * if we keep them separate we will not affect the lwip original code - * too much - * - * There will be a group for the all systems group address but this - * will not run the state machine as it is used to kick off reports - * from all the other groups - */ -struct igmp_group { - /** next link */ - struct igmp_group *next; - /** interface on which the group is active */ - struct netif *netif; - /** multicast address */ - ip_addr_t group_address; - /** signifies we were the last person to report */ - u8_t last_reporter_flag; - /** current state of the group */ - u8_t group_state; - /** timer for reporting, negative is OFF */ - u16_t timer; - /** counter of simultaneous uses */ - u8_t use; -}; - -/* Prototypes */ -void igmp_init(void); -err_t igmp_start(struct netif *netif); -err_t igmp_stop(struct netif *netif); -void igmp_report_groups(struct netif *netif); -struct igmp_group *igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr); -void igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest); -err_t igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); -err_t igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); -void igmp_tmr(void); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IGMP */ - -#endif /* __LWIP_IGMP_H__ */ +/* + * Copyright (c) 2002 CITEL Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. +*/ + +#ifndef __LWIP_IGMP_H__ +#define __LWIP_IGMP_H__ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/pbuf.h" + +#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* IGMP timer */ +#define IGMP_TMR_INTERVAL 100 /* Milliseconds */ +#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL) +#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL) + +/* MAC Filter Actions, these are passed to a netif's + * igmp_mac_filter callback function. */ +#define IGMP_DEL_MAC_FILTER 0 +#define IGMP_ADD_MAC_FILTER 1 + + +/** + * igmp group structure - there is + * a list of groups for each interface + * these should really be linked from the interface, but + * if we keep them separate we will not affect the lwip original code + * too much + * + * There will be a group for the all systems group address but this + * will not run the state machine as it is used to kick off reports + * from all the other groups + */ +struct igmp_group { + /** next link */ + struct igmp_group *next; + /** interface on which the group is active */ + struct netif *netif; + /** multicast address */ + ip_addr_t group_address; + /** signifies we were the last person to report */ + u8_t last_reporter_flag; + /** current state of the group */ + u8_t group_state; + /** timer for reporting, negative is OFF */ + u16_t timer; + /** counter of simultaneous uses */ + u8_t use; +}; + +/* Prototypes */ +void igmp_init(void); +err_t igmp_start(struct netif *netif); +err_t igmp_stop(struct netif *netif); +void igmp_report_groups(struct netif *netif); +struct igmp_group *igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr); +void igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest); +err_t igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); +err_t igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); +void igmp_tmr(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IGMP */ + +#endif /* __LWIP_IGMP_H__ */ diff --git a/include/lwip/ipv4/lwip/inet.h b/include/lwip/ipv4/lwip/inet.h index 391a9d8a..ec6d0909 100644 --- a/include/lwip/ipv4/lwip/inet.h +++ b/include/lwip/ipv4/lwip/inet.h @@ -1,112 +1,112 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_INET_H__ -#define __LWIP_INET_H__ - -#include "lwip/opt.h" -#include "lwip/def.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED) -typedef u32_t in_addr_t; -#endif -/** For compatibility with BSD code */ -struct in_addr { - in_addr_t s_addr; -}; - -/** 255.255.255.255 */ -#define INADDR_NONE IPADDR_NONE -/** 127.0.0.1 */ -#define INADDR_LOOPBACK IPADDR_LOOPBACK -/** 0.0.0.0 */ -#define INADDR_ANY IPADDR_ANY -/** 255.255.255.255 */ -#define INADDR_BROADCAST IPADDR_BROADCAST - -/* Definitions of the bits in an Internet address integer. - - On subnets, host and network parts are found according to - the subnet mask, not these masks. */ -#define IN_CLASSA(a) IP_CLASSA(a) -#define IN_CLASSA_NET IP_CLASSA_NET -#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT -#define IN_CLASSA_HOST IP_CLASSA_HOST -#define IN_CLASSA_MAX IP_CLASSA_MAX - -#define IN_CLASSB(b) IP_CLASSB(b) -#define IN_CLASSB_NET IP_CLASSB_NET -#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT -#define IN_CLASSB_HOST IP_CLASSB_HOST -#define IN_CLASSB_MAX IP_CLASSB_MAX - -#define IN_CLASSC(c) IP_CLASSC(c) -#define IN_CLASSC_NET IP_CLASSC_NET -#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT -#define IN_CLASSC_HOST IP_CLASSC_HOST -#define IN_CLASSC_MAX IP_CLASSC_MAX - -#define IN_CLASSD(d) IP_CLASSD(d) -#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */ -#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but */ -#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */ -#define IN_CLASSD_MAX IP_CLASSD_MAX - -#define IN_MULTICAST(a) IP_MULTICAST(a) - -#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a) -#define IN_BADCLASS(a) IP_BADCLASS(a) - -#define IN_LOOPBACKNET IP_LOOPBACKNET - -#define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) -#define inet_addr_to_ipaddr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) -/* ATTENTION: the next define only works because both s_addr and ip_addr_t are an u32_t effectively! */ -#define inet_addr_to_ipaddr_p(target_ipaddr_p, source_inaddr) ((target_ipaddr_p) = (ip_addr_t*)&((source_inaddr)->s_addr)) - -/* directly map this to the lwip internal functions */ -#define inet_addr(cp) ipaddr_addr(cp) -#define inet_aton(cp, addr) ipaddr_aton(cp, (ip_addr_t*)addr) -#define inet_ntoa(addr) ipaddr_ntoa((ip_addr_t*)&(addr)) -#define inet_ntoa_r(addr, buf, buflen) ipaddr_ntoa_r((ip_addr_t*)&(addr), buf, buflen) - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_INET_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INET_H__ +#define __LWIP_INET_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED) +typedef u32_t in_addr_t; +#endif +/** For compatibility with BSD code */ +struct in_addr { + in_addr_t s_addr; +}; + +/** 255.255.255.255 */ +#define INADDR_NONE IPADDR_NONE +/** 127.0.0.1 */ +#define INADDR_LOOPBACK IPADDR_LOOPBACK +/** 0.0.0.0 */ +#define INADDR_ANY IPADDR_ANY +/** 255.255.255.255 */ +#define INADDR_BROADCAST IPADDR_BROADCAST + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ +#define IN_CLASSA(a) IP_CLASSA(a) +#define IN_CLASSA_NET IP_CLASSA_NET +#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT +#define IN_CLASSA_HOST IP_CLASSA_HOST +#define IN_CLASSA_MAX IP_CLASSA_MAX + +#define IN_CLASSB(b) IP_CLASSB(b) +#define IN_CLASSB_NET IP_CLASSB_NET +#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT +#define IN_CLASSB_HOST IP_CLASSB_HOST +#define IN_CLASSB_MAX IP_CLASSB_MAX + +#define IN_CLASSC(c) IP_CLASSC(c) +#define IN_CLASSC_NET IP_CLASSC_NET +#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT +#define IN_CLASSC_HOST IP_CLASSC_HOST +#define IN_CLASSC_MAX IP_CLASSC_MAX + +#define IN_CLASSD(d) IP_CLASSD(d) +#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */ +#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but */ +#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */ +#define IN_CLASSD_MAX IP_CLASSD_MAX + +#define IN_MULTICAST(a) IP_MULTICAST(a) + +#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a) +#define IN_BADCLASS(a) IP_BADCLASS(a) + +#define IN_LOOPBACKNET IP_LOOPBACKNET + +#define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) +#define inet_addr_to_ipaddr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) +/* ATTENTION: the next define only works because both s_addr and ip_addr_t are an u32_t effectively! */ +#define inet_addr_to_ipaddr_p(target_ipaddr_p, source_inaddr) ((target_ipaddr_p) = (ip_addr_t*)&((source_inaddr)->s_addr)) + +/* directly map this to the lwip internal functions */ +#define inet_addr(cp) ipaddr_addr(cp) +#define inet_aton(cp, addr) ipaddr_aton(cp, (ip_addr_t*)addr) +#define inet_ntoa(addr) ipaddr_ntoa((ip_addr_t*)&(addr)) +#define inet_ntoa_r(addr, buf, buflen) ipaddr_ntoa_r((ip_addr_t*)&(addr), buf, buflen) + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ diff --git a/include/lwip/ipv4/lwip/ip4.h b/include/lwip/ipv4/lwip/ip4.h index 7c0d8646..04b5b8a6 100644 --- a/include/lwip/ipv4/lwip/ip4.h +++ b/include/lwip/ipv4/lwip/ip4.h @@ -1,146 +1,146 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_IP4_H__ -#define __LWIP_IP4_H__ - -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" -#include "lwip/err.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Currently, the function ip_output_if_opt() is only used with IGMP */ -#define IP_OPTIONS_SEND LWIP_IGMP - -#define IP_HLEN 20 - -#define IP_PROTO_ICMP 1 -#define IP_PROTO_IGMP 2 -#define IP_PROTO_UDP 17 -#define IP_PROTO_UDPLITE 136 -#define IP_PROTO_TCP 6 - - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip_hdr { - /* version / header length */ - PACK_STRUCT_FIELD(u8_t _v_hl); - /* type of service */ - PACK_STRUCT_FIELD(u8_t _tos); - /* total length */ - PACK_STRUCT_FIELD(u16_t _len); - /* identification */ - PACK_STRUCT_FIELD(u16_t _id); - /* fragment offset field */ - PACK_STRUCT_FIELD(u16_t _offset); -#define IP_RF 0x8000U /* reserved fragment flag */ -#define IP_DF 0x4000U /* dont fragment flag */ -#define IP_MF 0x2000U /* more fragments flag */ -#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ - /* time to live */ - PACK_STRUCT_FIELD(u8_t _ttl); - /* protocol*/ - PACK_STRUCT_FIELD(u8_t _proto); - /* checksum */ - PACK_STRUCT_FIELD(u16_t _chksum); - /* source and destination IP addresses */ - PACK_STRUCT_FIELD(ip_addr_p_t src); - PACK_STRUCT_FIELD(ip_addr_p_t dest); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define IPH_V(hdr) ((hdr)->_v_hl >> 4) -#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) -#define IPH_TOS(hdr) ((hdr)->_tos) -#define IPH_LEN(hdr) ((hdr)->_len) -#define IPH_ID(hdr) ((hdr)->_id) -#define IPH_OFFSET(hdr) ((hdr)->_offset) -#define IPH_TTL(hdr) ((hdr)->_ttl) -#define IPH_PROTO(hdr) ((hdr)->_proto) -#define IPH_CHKSUM(hdr) ((hdr)->_chksum) - -#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (((v) << 4) | (hl)) -#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) -#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) -#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) -#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) -#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) -#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) -#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) - - -#define ip_init() /* Compatibility define, no init needed. */ -struct netif *ip_route(ip_addr_t *dest); -err_t ip_input(struct pbuf *p, struct netif *inp); -err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto); -err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, - struct netif *netif); -#if LWIP_NETIF_HWADDRHINT -err_t ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT */ -#if IP_OPTIONS_SEND -err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen); -#endif /* IP_OPTIONS_SEND */ - -#define ip_netif_get_local_ipX(netif) (((netif) != NULL) ? ip_2_ipX(&((netif)->ip_addr)) : NULL) - -#if IP_DEBUG -void ip_debug_print(struct pbuf *p); -#else -#define ip_debug_print(p) -#endif /* IP_DEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP_H__ */ - - +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP4_H__ +#define __LWIP_IP4_H__ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" +#include "lwip/err.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Currently, the function ip_output_if_opt() is only used with IGMP */ +#define IP_OPTIONS_SEND LWIP_IGMP + +#define IP_HLEN 20 + +#define IP_PROTO_ICMP 1 +#define IP_PROTO_IGMP 2 +#define IP_PROTO_UDP 17 +#define IP_PROTO_UDPLITE 136 +#define IP_PROTO_TCP 6 + + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_hdr { + /* version / header length */ + PACK_STRUCT_FIELD(u8_t _v_hl); + /* type of service */ + PACK_STRUCT_FIELD(u8_t _tos); + /* total length */ + PACK_STRUCT_FIELD(u16_t _len); + /* identification */ + PACK_STRUCT_FIELD(u16_t _id); + /* fragment offset field */ + PACK_STRUCT_FIELD(u16_t _offset); +#define IP_RF 0x8000U /* reserved fragment flag */ +#define IP_DF 0x4000U /* dont fragment flag */ +#define IP_MF 0x2000U /* more fragments flag */ +#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ + /* time to live */ + PACK_STRUCT_FIELD(u8_t _ttl); + /* protocol*/ + PACK_STRUCT_FIELD(u8_t _proto); + /* checksum */ + PACK_STRUCT_FIELD(u16_t _chksum); + /* source and destination IP addresses */ + PACK_STRUCT_FIELD(ip_addr_p_t src); + PACK_STRUCT_FIELD(ip_addr_p_t dest); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IPH_V(hdr) ((hdr)->_v_hl >> 4) +#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) +#define IPH_TOS(hdr) ((hdr)->_tos) +#define IPH_LEN(hdr) ((hdr)->_len) +#define IPH_ID(hdr) ((hdr)->_id) +#define IPH_OFFSET(hdr) ((hdr)->_offset) +#define IPH_TTL(hdr) ((hdr)->_ttl) +#define IPH_PROTO(hdr) ((hdr)->_proto) +#define IPH_CHKSUM(hdr) ((hdr)->_chksum) + +#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (((v) << 4) | (hl)) +#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) +#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) +#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) +#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) +#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) +#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) +#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) + + +#define ip_init() /* Compatibility define, no init needed. */ +struct netif *ip_route(ip_addr_t *dest); +err_t ip_input(struct pbuf *p, struct netif *inp); +err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto); +err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, + struct netif *netif); +#if LWIP_NETIF_HWADDRHINT +err_t ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint); +#endif /* LWIP_NETIF_HWADDRHINT */ +#if IP_OPTIONS_SEND +err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen); +#endif /* IP_OPTIONS_SEND */ + +#define ip_netif_get_local_ipX(netif) (((netif) != NULL) ? ip_2_ipX(&((netif)->ip_addr)) : NULL) + +#if IP_DEBUG +void ip_debug_print(struct pbuf *p); +#else +#define ip_debug_print(p) +#endif /* IP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_H__ */ + + diff --git a/include/lwip/ipv4/lwip/ip4_addr.h b/include/lwip/ipv4/lwip/ip4_addr.h index 35b307ca..b05ae537 100644 --- a/include/lwip/ipv4/lwip/ip4_addr.h +++ b/include/lwip/ipv4/lwip/ip4_addr.h @@ -1,244 +1,244 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_IP4_ADDR_H__ -#define __LWIP_IP4_ADDR_H__ - -#include "lwip/opt.h" -#include "lwip/def.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* This is the aligned version of ip_addr_t, - used as local variable, on the stack, etc. */ -struct ip_addr { - u32_t addr; -}; - -/* This is the packed version of ip_addr_t, - used in network headers that are itself packed */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip_addr_packed { - PACK_STRUCT_FIELD(u32_t addr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** ip_addr_t uses a struct for convenience only, so that the same defines can - * operate both on ip_addr_t as well as on ip_addr_p_t. */ -typedef struct ip_addr ip_addr_t; -typedef struct ip_addr_packed ip_addr_p_t; - -/* - * struct ipaddr2 is used in the definition of the ARP packet format in - * order to support compilers that don't have structure packing. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip_addr2 { - PACK_STRUCT_FIELD(u16_t addrw[2]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Forward declaration to not include netif.h */ -struct netif; - -extern const ip_addr_t ip_addr_any; -extern const ip_addr_t ip_addr_broadcast; - -/** IP_ADDR_ can be used as a fixed IP address - * for the wildcard and the broadcast address - */ -#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any) -#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast) - -/** 255.255.255.255 */ -#define IPADDR_NONE ((u32_t)0xffffffffUL) -/** 127.0.0.1 */ -#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL) -/** 0.0.0.0 */ -#define IPADDR_ANY ((u32_t)0x00000000UL) -/** 255.255.255.255 */ -#define IPADDR_BROADCAST ((u32_t)0xffffffffUL) - -/* Definitions of the bits in an Internet address integer. - - On subnets, host and network parts are found according to - the subnet mask, not these masks. */ -#define IP_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0) -#define IP_CLASSA_NET 0xff000000 -#define IP_CLASSA_NSHIFT 24 -#define IP_CLASSA_HOST (0xffffffff & ~IP_CLASSA_NET) -#define IP_CLASSA_MAX 128 - -#define IP_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL) -#define IP_CLASSB_NET 0xffff0000 -#define IP_CLASSB_NSHIFT 16 -#define IP_CLASSB_HOST (0xffffffff & ~IP_CLASSB_NET) -#define IP_CLASSB_MAX 65536 - -#define IP_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL) -#define IP_CLASSC_NET 0xffffff00 -#define IP_CLASSC_NSHIFT 8 -#define IP_CLASSC_HOST (0xffffffff & ~IP_CLASSC_NET) - -#define IP_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL) -#define IP_CLASSD_NET 0xf0000000 /* These ones aren't really */ -#define IP_CLASSD_NSHIFT 28 /* net and host fields, but */ -#define IP_CLASSD_HOST 0x0fffffff /* routing needn't know. */ -#define IP_MULTICAST(a) IP_CLASSD(a) - -#define IP_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) -#define IP_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) - -#define IP_LOOPBACKNET 127 /* official! */ - - -#if BYTE_ORDER == BIG_ENDIAN -/** Set an IP address given by the four byte-parts */ -#define IP4_ADDR(ipaddr, a,b,c,d) \ - (ipaddr)->addr = ((u32_t)((a) & 0xff) << 24) | \ - ((u32_t)((b) & 0xff) << 16) | \ - ((u32_t)((c) & 0xff) << 8) | \ - (u32_t)((d) & 0xff) -#else -/** Set an IP address given by the four byte-parts. - Little-endian version that prevents the use of htonl. */ -#define IP4_ADDR(ipaddr, a,b,c,d) \ - (ipaddr)->addr = ((u32_t)((d) & 0xff) << 24) | \ - ((u32_t)((c) & 0xff) << 16) | \ - ((u32_t)((b) & 0xff) << 8) | \ - (u32_t)((a) & 0xff) -#endif - -/** MEMCPY-like copying of IP addresses where addresses are known to be - * 16-bit-aligned if the port is correctly configured (so a port could define - * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */ -#ifndef IPADDR2_COPY -#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip_addr_t)) -#endif - -/** Copy IP address - faster than ip_addr_set: no NULL check */ -#define ip_addr_copy(dest, src) ((dest).addr = (src).addr) -/** Safely copy one IP address to another (src may be NULL) */ -#define ip_addr_set(dest, src) ((dest)->addr = \ - ((src) == NULL ? 0 : \ - (src)->addr)) -/** Set complete address to zero */ -#define ip_addr_set_zero(ipaddr) ((ipaddr)->addr = 0) -/** Set address to IPADDR_ANY (no need for htonl()) */ -#define ip_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) -/** Set address to loopback address */ -#define ip_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK)) -/** Safely copy one IP address to another and change byte order - * from host- to network-order. */ -#define ip_addr_set_hton(dest, src) ((dest)->addr = \ - ((src) == NULL ? 0:\ - htonl((src)->addr))) -/** IPv4 only: set the IP address given as an u32_t */ -#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32)) -/** IPv4 only: get the IP address as an u32_t */ -#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr) - -/** Get the network address by combining host address with netmask */ -#define ip_addr_get_network(target, host, netmask) ((target)->addr = ((host)->addr) & ((netmask)->addr)) - -/** - * Determine if two address are on the same network. - * - * @arg addr1 IP address 1 - * @arg addr2 IP address 2 - * @arg mask network identifier mask - * @return !0 if the network identifiers of both address match - */ -#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \ - (mask)->addr) == \ - ((addr2)->addr & \ - (mask)->addr)) -#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr) - -#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == IPADDR_ANY) - -#define ip_addr_isbroadcast(ipaddr, netif) ip4_addr_isbroadcast((ipaddr)->addr, (netif)) -u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif); - -#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr) -u8_t ip4_addr_netmask_valid(u32_t netmask); - -#define ip_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL)) - -#define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL)) - -#define ip_addr_debug_print(debug, ipaddr) \ - LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \ - ipaddr != NULL ? ip4_addr1_16(ipaddr) : 0, \ - ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0, \ - ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0, \ - ipaddr != NULL ? ip4_addr4_16(ipaddr) : 0)) - -/* Get one byte from the 4-byte address */ -#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) -#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) -#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) -#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) -/* These are cast to u16_t, with the intent that they are often arguments - * to printf using the U16_F format from cc.h. */ -#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) -#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) -#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) -#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) - -/** For backwards compatibility */ -#define ip_ntoa(ipaddr) ipaddr_ntoa(ipaddr) - -u32_t ipaddr_addr(const char *cp); -int ipaddr_aton(const char *cp, ip_addr_t *addr); -/** returns ptr to static buffer; not reentrant! */ -char *ipaddr_ntoa(const ip_addr_t *addr); -char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen); - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP_ADDR_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP4_ADDR_H__ +#define __LWIP_IP4_ADDR_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the aligned version of ip_addr_t, + used as local variable, on the stack, etc. */ +struct ip_addr { + u32_t addr; +}; + +/* This is the packed version of ip_addr_t, + used in network headers that are itself packed */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr_packed { + PACK_STRUCT_FIELD(u32_t addr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** ip_addr_t uses a struct for convenience only, so that the same defines can + * operate both on ip_addr_t as well as on ip_addr_p_t. */ +typedef struct ip_addr ip_addr_t; +typedef struct ip_addr_packed ip_addr_p_t; + +/* + * struct ipaddr2 is used in the definition of the ARP packet format in + * order to support compilers that don't have structure packing. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr2 { + PACK_STRUCT_FIELD(u16_t addrw[2]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Forward declaration to not include netif.h */ +struct netif; + +extern const ip_addr_t ip_addr_any; +extern const ip_addr_t ip_addr_broadcast; + +/** IP_ADDR_ can be used as a fixed IP address + * for the wildcard and the broadcast address + */ +#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any) +#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast) + +/** 255.255.255.255 */ +#define IPADDR_NONE ((u32_t)0xffffffffUL) +/** 127.0.0.1 */ +#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL) +/** 0.0.0.0 */ +#define IPADDR_ANY ((u32_t)0x00000000UL) +/** 255.255.255.255 */ +#define IPADDR_BROADCAST ((u32_t)0xffffffffUL) + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ +#define IP_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0) +#define IP_CLASSA_NET 0xff000000 +#define IP_CLASSA_NSHIFT 24 +#define IP_CLASSA_HOST (0xffffffff & ~IP_CLASSA_NET) +#define IP_CLASSA_MAX 128 + +#define IP_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL) +#define IP_CLASSB_NET 0xffff0000 +#define IP_CLASSB_NSHIFT 16 +#define IP_CLASSB_HOST (0xffffffff & ~IP_CLASSB_NET) +#define IP_CLASSB_MAX 65536 + +#define IP_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL) +#define IP_CLASSC_NET 0xffffff00 +#define IP_CLASSC_NSHIFT 8 +#define IP_CLASSC_HOST (0xffffffff & ~IP_CLASSC_NET) + +#define IP_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL) +#define IP_CLASSD_NET 0xf0000000 /* These ones aren't really */ +#define IP_CLASSD_NSHIFT 28 /* net and host fields, but */ +#define IP_CLASSD_HOST 0x0fffffff /* routing needn't know. */ +#define IP_MULTICAST(a) IP_CLASSD(a) + +#define IP_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) +#define IP_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) + +#define IP_LOOPBACKNET 127 /* official! */ + + +#if BYTE_ORDER == BIG_ENDIAN +/** Set an IP address given by the four byte-parts */ +#define IP4_ADDR(ipaddr, a,b,c,d) \ + (ipaddr)->addr = ((u32_t)((a) & 0xff) << 24) | \ + ((u32_t)((b) & 0xff) << 16) | \ + ((u32_t)((c) & 0xff) << 8) | \ + (u32_t)((d) & 0xff) +#else +/** Set an IP address given by the four byte-parts. + Little-endian version that prevents the use of htonl. */ +#define IP4_ADDR(ipaddr, a,b,c,d) \ + (ipaddr)->addr = ((u32_t)((d) & 0xff) << 24) | \ + ((u32_t)((c) & 0xff) << 16) | \ + ((u32_t)((b) & 0xff) << 8) | \ + (u32_t)((a) & 0xff) +#endif + +/** MEMCPY-like copying of IP addresses where addresses are known to be + * 16-bit-aligned if the port is correctly configured (so a port could define + * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */ +#ifndef IPADDR2_COPY +#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip_addr_t)) +#endif + +/** Copy IP address - faster than ip_addr_set: no NULL check */ +#define ip_addr_copy(dest, src) ((dest).addr = (src).addr) +/** Safely copy one IP address to another (src may be NULL) */ +#define ip_addr_set(dest, src) ((dest)->addr = \ + ((src) == NULL ? 0 : \ + (src)->addr)) +/** Set complete address to zero */ +#define ip_addr_set_zero(ipaddr) ((ipaddr)->addr = 0) +/** Set address to IPADDR_ANY (no need for htonl()) */ +#define ip_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) +/** Set address to loopback address */ +#define ip_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK)) +/** Safely copy one IP address to another and change byte order + * from host- to network-order. */ +#define ip_addr_set_hton(dest, src) ((dest)->addr = \ + ((src) == NULL ? 0:\ + htonl((src)->addr))) +/** IPv4 only: set the IP address given as an u32_t */ +#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32)) +/** IPv4 only: get the IP address as an u32_t */ +#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr) + +/** Get the network address by combining host address with netmask */ +#define ip_addr_get_network(target, host, netmask) ((target)->addr = ((host)->addr) & ((netmask)->addr)) + +/** + * Determine if two address are on the same network. + * + * @arg addr1 IP address 1 + * @arg addr2 IP address 2 + * @arg mask network identifier mask + * @return !0 if the network identifiers of both address match + */ +#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \ + (mask)->addr) == \ + ((addr2)->addr & \ + (mask)->addr)) +#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr) + +#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == IPADDR_ANY) + +#define ip_addr_isbroadcast(ipaddr, netif) ip4_addr_isbroadcast((ipaddr)->addr, (netif)) +u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif); + +#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr) +u8_t ip4_addr_netmask_valid(u32_t netmask); + +#define ip_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL)) + +#define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL)) + +#define ip_addr_debug_print(debug, ipaddr) \ + LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \ + ipaddr != NULL ? ip4_addr1_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr4_16(ipaddr) : 0)) + +/* Get one byte from the 4-byte address */ +#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) +#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) +#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) +#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) +/* These are cast to u16_t, with the intent that they are often arguments + * to printf using the U16_F format from cc.h. */ +#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) +#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) +#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) +#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) + +/** For backwards compatibility */ +#define ip_ntoa(ipaddr) ipaddr_ntoa(ipaddr) + +u32_t ipaddr_addr(const char *cp); +int ipaddr_aton(const char *cp, ip_addr_t *addr); +/** returns ptr to static buffer; not reentrant! */ +char *ipaddr_ntoa(const ip_addr_t *addr); +char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/include/lwip/ipv4/lwip/ip_frag.h b/include/lwip/ipv4/lwip/ip_frag.h index c78f2c56..47eca9f4 100644 --- a/include/lwip/ipv4/lwip/ip_frag.h +++ b/include/lwip/ipv4/lwip/ip_frag.h @@ -1,91 +1,91 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Jani Monoses - * - */ - -#ifndef __LWIP_IP_FRAG_H__ -#define __LWIP_IP_FRAG_H__ - -#include "lwip/opt.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/ip_addr.h" -#include "lwip/ip.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if IP_REASSEMBLY -/* The IP reassembly timer interval in milliseconds. */ -#define IP_TMR_INTERVAL 1000 - -/* IP reassembly helper struct. - * This is exported because memp needs to know the size. - */ -struct ip_reassdata { - struct ip_reassdata *next; - struct pbuf *p; - struct ip_hdr iphdr; - u16_t datagram_len; - u8_t flags; - u8_t timer; -}; - -void ip_reass_init(void); -void ip_reass_tmr(void); -struct pbuf * ip_reass(struct pbuf *p); -#endif /* IP_REASSEMBLY */ - -#if IP_FRAG -#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF -/** A custom pbuf that holds a reference to another pbuf, which is freed - * when this custom pbuf is freed. This is used to create a custom PBUF_REF - * that points into the original pbuf. */ -#ifndef __LWIP_PBUF_CUSTOM_REF__ -#define __LWIP_PBUF_CUSTOM_REF__ -struct pbuf_custom_ref { - /** 'base class' */ - struct pbuf_custom pc; - /** pointer to the original pbuf that is referenced */ - struct pbuf *original; -}; -#endif /* __LWIP_PBUF_CUSTOM_REF__ */ -#endif /* !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ - -err_t ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest); -#endif /* IP_FRAG */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP_FRAG_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jani Monoses + * + */ + +#ifndef __LWIP_IP_FRAG_H__ +#define __LWIP_IP_FRAG_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/ip_addr.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if IP_REASSEMBLY +/* The IP reassembly timer interval in milliseconds. */ +#define IP_TMR_INTERVAL 1000 + +/* IP reassembly helper struct. + * This is exported because memp needs to know the size. + */ +struct ip_reassdata { + struct ip_reassdata *next; + struct pbuf *p; + struct ip_hdr iphdr; + u16_t datagram_len; + u8_t flags; + u8_t timer; +}; + +void ip_reass_init(void); +void ip_reass_tmr(void); +struct pbuf * ip_reass(struct pbuf *p); +#endif /* IP_REASSEMBLY */ + +#if IP_FRAG +#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF +/** A custom pbuf that holds a reference to another pbuf, which is freed + * when this custom pbuf is freed. This is used to create a custom PBUF_REF + * that points into the original pbuf. */ +#ifndef __LWIP_PBUF_CUSTOM_REF__ +#define __LWIP_PBUF_CUSTOM_REF__ +struct pbuf_custom_ref { + /** 'base class' */ + struct pbuf_custom pc; + /** pointer to the original pbuf that is referenced */ + struct pbuf *original; +}; +#endif /* __LWIP_PBUF_CUSTOM_REF__ */ +#endif /* !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ + +err_t ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest); +#endif /* IP_FRAG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_FRAG_H__ */ diff --git a/include/lwip/ipv6/lwip/dhcp6.h b/include/lwip/ipv6/lwip/dhcp6.h index 8fec444f..4b905c54 100644 --- a/include/lwip/ipv6/lwip/dhcp6.h +++ b/include/lwip/ipv6/lwip/dhcp6.h @@ -1,58 +1,58 @@ -/** - * @file - * - * IPv6 address autoconfiguration as per RFC 4862. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * IPv6 address autoconfiguration as per RFC 4862. - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef __LWIP_IP6_DHCP6_H__ -#define __LWIP_IP6_DHCP6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ - - -struct dhcp6 -{ - /*TODO: implement DHCP6*/ -}; - -#endif /* LWIP_IPV6_DHCP6 */ - -#endif /* __LWIP_IP6_DHCP6_H__ */ +/** + * @file + * + * IPv6 address autoconfiguration as per RFC 4862. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * IPv6 address autoconfiguration as per RFC 4862. + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#ifndef __LWIP_IP6_DHCP6_H__ +#define __LWIP_IP6_DHCP6_H__ + +#include "lwip/opt.h" + +#if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ + + +struct dhcp6 +{ + /*TODO: implement DHCP6*/ +}; + +#endif /* LWIP_IPV6_DHCP6 */ + +#endif /* __LWIP_IP6_DHCP6_H__ */ diff --git a/include/lwip/ipv6/lwip/ethip6.h b/include/lwip/ipv6/lwip/ethip6.h index d7302678..e7f412b4 100644 --- a/include/lwip/ipv6/lwip/ethip6.h +++ b/include/lwip/ipv6/lwip/ethip6.h @@ -1,68 +1,68 @@ -/** - * @file - * - * Ethernet output for IPv6. Uses ND tables for link-layer addressing. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef __LWIP_ETHIP6_H__ -#define __LWIP_ETHIP6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -err_t ethip6_output(struct netif *netif, struct pbuf *q, ip6_addr_t *ip6addr); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 && LWIP_ETHERNET */ - -#endif /* __LWIP_ETHIP6_H__ */ +/** + * @file + * + * Ethernet output for IPv6. Uses ND tables for link-layer addressing. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#ifndef __LWIP_ETHIP6_H__ +#define __LWIP_ETHIP6_H__ + +#include "lwip/opt.h" + +#if LWIP_IPV6 && LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/netif.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +err_t ethip6_output(struct netif *netif, struct pbuf *q, ip6_addr_t *ip6addr); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6 && LWIP_ETHERNET */ + +#endif /* __LWIP_ETHIP6_H__ */ diff --git a/include/lwip/ipv6/lwip/icmp6.h b/include/lwip/ipv6/lwip/icmp6.h index a40c5b40..74bfdbe0 100644 --- a/include/lwip/ipv6/lwip/icmp6.h +++ b/include/lwip/ipv6/lwip/icmp6.h @@ -1,152 +1,152 @@ -/** - * @file - * - * IPv6 version of ICMP, as per RFC 4443. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef __LWIP_ICMP6_H__ -#define __LWIP_ICMP6_H__ - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -enum icmp6_type { - ICMP6_TYPE_DUR = 1, /* Destination unreachable */ - ICMP6_TYPE_PTB = 2, /* Packet too big */ - ICMP6_TYPE_TE = 3, /* Time exceeded */ - ICMP6_TYPE_PP = 4, /* Parameter problem */ - ICMP6_TYPE_PE1 = 100, /* Private experimentation */ - ICMP6_TYPE_PE2 = 101, /* Private experimentation */ - ICMP6_TYPE_RSV_ERR = 127, /* Reserved for expansion of error messages */ - - ICMP6_TYPE_EREQ = 128, /* Echo request */ - ICMP6_TYPE_EREP = 129, /* Echo reply */ - ICMP6_TYPE_MLQ = 130, /* Multicast listener query */ - ICMP6_TYPE_MLR = 131, /* Multicast listener report */ - ICMP6_TYPE_MLD = 132, /* Multicast listener done */ - ICMP6_TYPE_RS = 133, /* Router solicitation */ - ICMP6_TYPE_RA = 134, /* Router advertisement */ - ICMP6_TYPE_NS = 135, /* Neighbor solicitation */ - ICMP6_TYPE_NA = 136, /* Neighbor advertisement */ - ICMP6_TYPE_RD = 137, /* Redirect */ - ICMP6_TYPE_MRA = 151, /* Multicast router advertisement */ - ICMP6_TYPE_MRS = 152, /* Multicast router solicitation */ - ICMP6_TYPE_MRT = 153, /* Multicast router termination */ - ICMP6_TYPE_PE3 = 200, /* Private experimentation */ - ICMP6_TYPE_PE4 = 201, /* Private experimentation */ - ICMP6_TYPE_RSV_INF = 255 /* Reserved for expansion of informational messages */ -}; - -enum icmp6_dur_code { - ICMP6_DUR_NO_ROUTE = 0, /* No route to destination */ - ICMP6_DUR_PROHIBITED = 1, /* Communication with destination administratively prohibited */ - ICMP6_DUR_SCOPE = 2, /* Beyond scope of source address */ - ICMP6_DUR_ADDRESS = 3, /* Address unreachable */ - ICMP6_DUR_PORT = 4, /* Port unreachable */ - ICMP6_DUR_POLICY = 5, /* Source address failed ingress/egress policy */ - ICMP6_DUR_REJECT_ROUTE = 6 /* Reject route to destination */ -}; - -enum icmp6_te_code { - ICMP6_TE_HL = 0, /* Hop limit exceeded in transit */ - ICMP6_TE_FRAG = 1 /* Fragment reassembly time exceeded */ -}; - -enum icmp6_pp_code { - ICMP6_PP_FIELD = 0, /* Erroneous header field encountered */ - ICMP6_PP_HEADER = 1, /* Unrecognized next header type encountered */ - ICMP6_PP_OPTION = 2 /* Unrecognized IPv6 option encountered */ -}; - -/** This is the standard ICMP6 header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct icmp6_hdr { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t data); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** This is the ICMP6 header adapted for echo req/resp. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct icmp6_echo_hdr { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FIELD(u16_t seqno); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -void icmp6_input(struct pbuf *p, struct netif *inp); -void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c); -void icmp6_packet_too_big(struct pbuf *p, u32_t mtu); -void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c); -void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer); - -#endif /* LWIP_ICMP6 && LWIP_IPV6 */ - - -#ifdef __cplusplus -} -#endif - - -#endif /* __LWIP_ICMP6_H__ */ +/** + * @file + * + * IPv6 version of ICMP, as per RFC 4443. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ +#ifndef __LWIP_ICMP6_H__ +#define __LWIP_ICMP6_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip6_addr.h" +#include "lwip/netif.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +enum icmp6_type { + ICMP6_TYPE_DUR = 1, /* Destination unreachable */ + ICMP6_TYPE_PTB = 2, /* Packet too big */ + ICMP6_TYPE_TE = 3, /* Time exceeded */ + ICMP6_TYPE_PP = 4, /* Parameter problem */ + ICMP6_TYPE_PE1 = 100, /* Private experimentation */ + ICMP6_TYPE_PE2 = 101, /* Private experimentation */ + ICMP6_TYPE_RSV_ERR = 127, /* Reserved for expansion of error messages */ + + ICMP6_TYPE_EREQ = 128, /* Echo request */ + ICMP6_TYPE_EREP = 129, /* Echo reply */ + ICMP6_TYPE_MLQ = 130, /* Multicast listener query */ + ICMP6_TYPE_MLR = 131, /* Multicast listener report */ + ICMP6_TYPE_MLD = 132, /* Multicast listener done */ + ICMP6_TYPE_RS = 133, /* Router solicitation */ + ICMP6_TYPE_RA = 134, /* Router advertisement */ + ICMP6_TYPE_NS = 135, /* Neighbor solicitation */ + ICMP6_TYPE_NA = 136, /* Neighbor advertisement */ + ICMP6_TYPE_RD = 137, /* Redirect */ + ICMP6_TYPE_MRA = 151, /* Multicast router advertisement */ + ICMP6_TYPE_MRS = 152, /* Multicast router solicitation */ + ICMP6_TYPE_MRT = 153, /* Multicast router termination */ + ICMP6_TYPE_PE3 = 200, /* Private experimentation */ + ICMP6_TYPE_PE4 = 201, /* Private experimentation */ + ICMP6_TYPE_RSV_INF = 255 /* Reserved for expansion of informational messages */ +}; + +enum icmp6_dur_code { + ICMP6_DUR_NO_ROUTE = 0, /* No route to destination */ + ICMP6_DUR_PROHIBITED = 1, /* Communication with destination administratively prohibited */ + ICMP6_DUR_SCOPE = 2, /* Beyond scope of source address */ + ICMP6_DUR_ADDRESS = 3, /* Address unreachable */ + ICMP6_DUR_PORT = 4, /* Port unreachable */ + ICMP6_DUR_POLICY = 5, /* Source address failed ingress/egress policy */ + ICMP6_DUR_REJECT_ROUTE = 6 /* Reject route to destination */ +}; + +enum icmp6_te_code { + ICMP6_TE_HL = 0, /* Hop limit exceeded in transit */ + ICMP6_TE_FRAG = 1 /* Fragment reassembly time exceeded */ +}; + +enum icmp6_pp_code { + ICMP6_PP_FIELD = 0, /* Erroneous header field encountered */ + ICMP6_PP_HEADER = 1, /* Unrecognized next header type encountered */ + ICMP6_PP_OPTION = 2 /* Unrecognized IPv6 option encountered */ +}; + +/** This is the standard ICMP6 header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct icmp6_hdr { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t data); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** This is the ICMP6 header adapted for echo req/resp. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct icmp6_echo_hdr { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u16_t seqno); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +void icmp6_input(struct pbuf *p, struct netif *inp); +void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c); +void icmp6_packet_too_big(struct pbuf *p, u32_t mtu); +void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c); +void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer); + +#endif /* LWIP_ICMP6 && LWIP_IPV6 */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* __LWIP_ICMP6_H__ */ diff --git a/include/lwip/ipv6/lwip/inet6.h b/include/lwip/ipv6/lwip/inet6.h index 924a3246..8359521b 100644 --- a/include/lwip/ipv6/lwip/inet6.h +++ b/include/lwip/ipv6/lwip/inet6.h @@ -1,92 +1,92 @@ -/** - * @file - * - * INET v6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef __LWIP_INET6_H__ -#define __LWIP_INET6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/def.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** For compatibility with BSD code */ -struct in6_addr { - union { - u8_t u8_addr[16]; - u32_t u32_addr[4]; - } un; -#define s6_addr un.u8_addr -}; - -#define IN6ADDR_ANY_INIT {0,0,0,0} -#define IN6ADDR_LOOPBACK_INIT {0,0,0,PP_HTONL(1)} - - -#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \ - (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \ - (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \ - (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];} -#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \ - (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \ - (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \ - (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];} -/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */ -#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr)) - -/* directly map this to the lwip internal functions */ -#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr) -#define inet6_ntoa(addr) ip6addr_ntoa((ip6_addr_t*)&(addr)) -#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((ip6_addr_t*)&(addr), buf, buflen) - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* __LWIP_INET6_H__ */ - +/** + * @file + * + * INET v6 addresses. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ +#ifndef __LWIP_INET6_H__ +#define __LWIP_INET6_H__ + +#include "lwip/opt.h" + +#if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/ip6_addr.h" +#include "lwip/def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** For compatibility with BSD code */ +struct in6_addr { + union { + u8_t u8_addr[16]; + u32_t u32_addr[4]; + } un; +#define s6_addr un.u8_addr +}; + +#define IN6ADDR_ANY_INIT {0,0,0,0} +#define IN6ADDR_LOOPBACK_INIT {0,0,0,PP_HTONL(1)} + + +#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \ + (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \ + (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \ + (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];} +#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \ + (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \ + (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \ + (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];} +/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */ +#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr)) + +/* directly map this to the lwip internal functions */ +#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr) +#define inet6_ntoa(addr) ip6addr_ntoa((ip6_addr_t*)&(addr)) +#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((ip6_addr_t*)&(addr), buf, buflen) + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6 */ + +#endif /* __LWIP_INET6_H__ */ + diff --git a/include/lwip/ipv6/lwip/ip6.h b/include/lwip/ipv6/lwip/ip6.h index f027022f..ac32ceec 100644 --- a/include/lwip/ipv6/lwip/ip6.h +++ b/include/lwip/ipv6/lwip/ip6.h @@ -1,196 +1,196 @@ -/** - * @file - * - * IPv6 layer. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef __LWIP_IP6_H__ -#define __LWIP_IP6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" - -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define IP6_HLEN 40 - -#define IP6_NEXTH_HOPBYHOP 0 -#define IP6_NEXTH_TCP 6 -#define IP6_NEXTH_UDP 17 -#define IP6_NEXTH_ENCAPS 41 -#define IP6_NEXTH_ROUTING 43 -#define IP6_NEXTH_FRAGMENT 44 -#define IP6_NEXTH_ICMP6 58 -#define IP6_NEXTH_NONE 59 -#define IP6_NEXTH_DESTOPTS 60 -#define IP6_NEXTH_UDPLITE 136 - - -/* The IPv6 header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_hdr { - /* version / traffic class / flow label */ - PACK_STRUCT_FIELD(u32_t _v_tc_fl); - /* payload length */ - PACK_STRUCT_FIELD(u16_t _plen); - /* next header */ - PACK_STRUCT_FIELD(u8_t _nexth); - /* hop limit */ - PACK_STRUCT_FIELD(u8_t _hoplim); - /* source and destination IP addresses */ - PACK_STRUCT_FIELD(ip6_addr_p_t src); - PACK_STRUCT_FIELD(ip6_addr_p_t dest); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Hop-by-hop router alert option. */ -#define IP6_HBH_HLEN 8 -#define IP6_PAD1_OPTION 0 -#define IP6_PADN_ALERT_OPTION 1 -#define IP6_ROUTER_ALERT_OPTION 5 -#define IP6_ROUTER_ALERT_VALUE_MLD 0 -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_hbh_hdr { - /* next header */ - PACK_STRUCT_FIELD(u8_t _nexth); - /* header length */ - PACK_STRUCT_FIELD(u8_t _hlen); - /* router alert option type */ - PACK_STRUCT_FIELD(u8_t _ra_opt_type); - /* router alert option data len */ - PACK_STRUCT_FIELD(u8_t _ra_opt_dlen); - /* router alert option data */ - PACK_STRUCT_FIELD(u16_t _ra_opt_data); - /* PadN option type */ - PACK_STRUCT_FIELD(u8_t _padn_opt_type); - /* PadN option data len */ - PACK_STRUCT_FIELD(u8_t _padn_opt_dlen); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Fragment header. */ -#define IP6_FRAG_HLEN 8 -#define IP6_FRAG_OFFSET_MASK 0xfff8 -#define IP6_FRAG_MORE_FLAG 0x0001 -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_frag_hdr { - /* next header */ - PACK_STRUCT_FIELD(u8_t _nexth); - /* reserved */ - PACK_STRUCT_FIELD(u8_t reserved); - /* fragment offset */ - PACK_STRUCT_FIELD(u16_t _fragment_offset); - /* fragmented packet identification */ - PACK_STRUCT_FIELD(u32_t _identification); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define IP6H_V(hdr) ((ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f) -#define IP6H_TC(hdr) ((ntohl((hdr)->_v_tc_fl) >> 20) & 0xff) -#define IP6H_FL(hdr) (ntohl((hdr)->_v_tc_fl) & 0x000fffff) -#define IP6H_PLEN(hdr) (ntohs((hdr)->_plen)) -#define IP6H_NEXTH(hdr) ((hdr)->_nexth) -#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6) -#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim) - -#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (htonl(((v) << 28) | ((tc) << 20) | (fl))) -#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = htons(plen) -#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth) -#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl) - - -#define ip6_init() /* TODO should we init current addresses and header pointer? */ -struct netif *ip6_route(struct ip6_addr *src, struct ip6_addr *dest); -ip6_addr_t *ip6_select_source_address(struct netif *netif, ip6_addr_t * dest); -err_t ip6_input(struct pbuf *p, struct netif *inp); -err_t ip6_output(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, - u8_t hl, u8_t tc, u8_t nexth); -err_t ip6_output_if(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, - u8_t hl, u8_t tc, u8_t nexth, struct netif *netif); -#if LWIP_NETIF_HWADDRHINT -err_t ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT */ -#if LWIP_IPV6_MLD -err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value); -#endif /* LWIP_IPV6_MLD */ - -#define ip6_netif_get_local_ipX(netif, dest) (((netif) != NULL) ? \ - ip6_2_ipX(ip6_select_source_address(netif, dest)) : NULL) - -#if IP6_DEBUG -void ip6_debug_print(struct pbuf *p); -#else -#define ip6_debug_print(p) -#endif /* IP6_DEBUG */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* __LWIP_IP6_H__ */ +/** + * @file + * + * IPv6 layer. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ +#ifndef __LWIP_IP6_H__ +#define __LWIP_IP6_H__ + +#include "lwip/opt.h" + +#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/ip6_addr.h" +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" + +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP6_HLEN 40 + +#define IP6_NEXTH_HOPBYHOP 0 +#define IP6_NEXTH_TCP 6 +#define IP6_NEXTH_UDP 17 +#define IP6_NEXTH_ENCAPS 41 +#define IP6_NEXTH_ROUTING 43 +#define IP6_NEXTH_FRAGMENT 44 +#define IP6_NEXTH_ICMP6 58 +#define IP6_NEXTH_NONE 59 +#define IP6_NEXTH_DESTOPTS 60 +#define IP6_NEXTH_UDPLITE 136 + + +/* The IPv6 header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_hdr { + /* version / traffic class / flow label */ + PACK_STRUCT_FIELD(u32_t _v_tc_fl); + /* payload length */ + PACK_STRUCT_FIELD(u16_t _plen); + /* next header */ + PACK_STRUCT_FIELD(u8_t _nexth); + /* hop limit */ + PACK_STRUCT_FIELD(u8_t _hoplim); + /* source and destination IP addresses */ + PACK_STRUCT_FIELD(ip6_addr_p_t src); + PACK_STRUCT_FIELD(ip6_addr_p_t dest); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Hop-by-hop router alert option. */ +#define IP6_HBH_HLEN 8 +#define IP6_PAD1_OPTION 0 +#define IP6_PADN_ALERT_OPTION 1 +#define IP6_ROUTER_ALERT_OPTION 5 +#define IP6_ROUTER_ALERT_VALUE_MLD 0 +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_hbh_hdr { + /* next header */ + PACK_STRUCT_FIELD(u8_t _nexth); + /* header length */ + PACK_STRUCT_FIELD(u8_t _hlen); + /* router alert option type */ + PACK_STRUCT_FIELD(u8_t _ra_opt_type); + /* router alert option data len */ + PACK_STRUCT_FIELD(u8_t _ra_opt_dlen); + /* router alert option data */ + PACK_STRUCT_FIELD(u16_t _ra_opt_data); + /* PadN option type */ + PACK_STRUCT_FIELD(u8_t _padn_opt_type); + /* PadN option data len */ + PACK_STRUCT_FIELD(u8_t _padn_opt_dlen); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Fragment header. */ +#define IP6_FRAG_HLEN 8 +#define IP6_FRAG_OFFSET_MASK 0xfff8 +#define IP6_FRAG_MORE_FLAG 0x0001 +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_frag_hdr { + /* next header */ + PACK_STRUCT_FIELD(u8_t _nexth); + /* reserved */ + PACK_STRUCT_FIELD(u8_t reserved); + /* fragment offset */ + PACK_STRUCT_FIELD(u16_t _fragment_offset); + /* fragmented packet identification */ + PACK_STRUCT_FIELD(u32_t _identification); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IP6H_V(hdr) ((ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f) +#define IP6H_TC(hdr) ((ntohl((hdr)->_v_tc_fl) >> 20) & 0xff) +#define IP6H_FL(hdr) (ntohl((hdr)->_v_tc_fl) & 0x000fffff) +#define IP6H_PLEN(hdr) (ntohs((hdr)->_plen)) +#define IP6H_NEXTH(hdr) ((hdr)->_nexth) +#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6) +#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim) + +#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (htonl(((v) << 28) | ((tc) << 20) | (fl))) +#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = htons(plen) +#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth) +#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl) + + +#define ip6_init() /* TODO should we init current addresses and header pointer? */ +struct netif *ip6_route(struct ip6_addr *src, struct ip6_addr *dest); +ip6_addr_t *ip6_select_source_address(struct netif *netif, ip6_addr_t * dest); +err_t ip6_input(struct pbuf *p, struct netif *inp); +err_t ip6_output(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, + u8_t hl, u8_t tc, u8_t nexth); +err_t ip6_output_if(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, + u8_t hl, u8_t tc, u8_t nexth, struct netif *netif); +#if LWIP_NETIF_HWADDRHINT +err_t ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, + u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint); +#endif /* LWIP_NETIF_HWADDRHINT */ +#if LWIP_IPV6_MLD +err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value); +#endif /* LWIP_IPV6_MLD */ + +#define ip6_netif_get_local_ipX(netif, dest) (((netif) != NULL) ? \ + ip6_2_ipX(ip6_select_source_address(netif, dest)) : NULL) + +#if IP6_DEBUG +void ip6_debug_print(struct pbuf *p); +#else +#define ip6_debug_print(p) +#endif /* IP6_DEBUG */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6 */ + +#endif /* __LWIP_IP6_H__ */ diff --git a/include/lwip/ipv6/lwip/ip6_addr.h b/include/lwip/ipv6/lwip/ip6_addr.h index 511da7f9..89b5b811 100644 --- a/include/lwip/ipv6/lwip/ip6_addr.h +++ b/include/lwip/ipv6/lwip/ip6_addr.h @@ -1,286 +1,286 @@ -/** - * @file - * - * IPv6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * Structs and macros for handling IPv6 addresses. - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef __LWIP_IP6_ADDR_H__ -#define __LWIP_IP6_ADDR_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* This is the aligned version of ip6_addr_t, - used as local variable, on the stack, etc. */ -struct ip6_addr { - u32_t addr[4]; -}; - -/* This is the packed version of ip6_addr_t, - used in network headers that are itself packed */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_addr_packed { - PACK_STRUCT_FIELD(u32_t addr[4]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** ip6_addr_t uses a struct for convenience only, so that the same defines can - * operate both on ip6_addr_t as well as on ip6_addr_p_t. */ -typedef struct ip6_addr ip6_addr_t; -typedef struct ip6_addr_packed ip6_addr_p_t; - - -/** IP6_ADDR_ANY can be used as a fixed IPv6 address - * for the wildcard - */ -extern const ip6_addr_t ip6_addr_any; -#define IP6_ADDR_ANY ((ip6_addr_t *)&ip6_addr_any) - - - - -#if BYTE_ORDER == BIG_ENDIAN -/** Set an IPv6 partial address given by byte-parts. */ -#define IP6_ADDR(ip6addr, index, a,b,c,d) \ - (ip6addr)->addr[index] = ((u32_t)((a) & 0xff) << 24) | \ - ((u32_t)((b) & 0xff) << 16) | \ - ((u32_t)((c) & 0xff) << 8) | \ - (u32_t)((d) & 0xff) -#else -/** Set an IPv6 partial address given by byte-parts. -Little-endian version, stored in network order (no htonl). */ -#define IP6_ADDR(ip6addr, index, a,b,c,d) \ - (ip6addr)->addr[index] = ((u32_t)((d) & 0xff) << 24) | \ - ((u32_t)((c) & 0xff) << 16) | \ - ((u32_t)((b) & 0xff) << 8) | \ - (u32_t)((a) & 0xff) -#endif - -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)(htonl((ip6addr)->addr[0]) >> 16) & 0xffff) -#define IP6_ADDR_BLOCK2(ip6addr) ((u16_t)(htonl((ip6addr)->addr[0])) & 0xffff) -#define IP6_ADDR_BLOCK3(ip6addr) ((u16_t)(htonl((ip6addr)->addr[1]) >> 16) & 0xffff) -#define IP6_ADDR_BLOCK4(ip6addr) ((u16_t)(htonl((ip6addr)->addr[1])) & 0xffff) -#define IP6_ADDR_BLOCK5(ip6addr) ((u16_t)(htonl((ip6addr)->addr[2]) >> 16) & 0xffff) -#define IP6_ADDR_BLOCK6(ip6addr) ((u16_t)(htonl((ip6addr)->addr[2])) & 0xffff) -#define IP6_ADDR_BLOCK7(ip6addr) ((u16_t)(htonl((ip6addr)->addr[3]) >> 16) & 0xffff) -#define IP6_ADDR_BLOCK8(ip6addr) ((u16_t)(htonl((ip6addr)->addr[3])) & 0xffff) - -/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */ -#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \ - (dest).addr[1] = (src).addr[1]; \ - (dest).addr[2] = (src).addr[2]; \ - (dest).addr[3] = (src).addr[3];}while(0) -/** Safely copy one IPv6 address to another (src may be NULL) */ -#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \ - (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \ - (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \ - (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0) - -/** Set complete address to zero */ -#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = 0;}while(0) - -/** Set address to ipv6 'any' (no need for htonl()) */ -#define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr) -/** Set address to ipv6 loopback address */ -#define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) -/** Safely copy one IPv6 address to another and change byte order - * from host- to network-order. */ -#define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : htonl((src)->addr[0]); \ - (dest)->addr[1] = (src) == NULL ? 0 : htonl((src)->addr[1]); \ - (dest)->addr[2] = (src) == NULL ? 0 : htonl((src)->addr[2]); \ - (dest)->addr[3] = (src) == NULL ? 0 : htonl((src)->addr[3]);}while(0) - - - -/** - * Determine if two IPv6 address are on the same network. - * - * @arg addr1 IPv6 address 1 - * @arg addr2 IPv6 address 2 - * @return !0 if the network identifiers of both address match - */ -#define ip6_addr_netcmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ - ((addr1)->addr[1] == (addr2)->addr[1])) - -#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ - ((addr1)->addr[1] == (addr2)->addr[1]) && \ - ((addr1)->addr[2] == (addr2)->addr[2]) && \ - ((addr1)->addr[3] == (addr2)->addr[3])) - -#define ip6_get_subnet_id(ip6addr) (htonl((ip6addr)->addr[2]) & 0x0000ffffUL) - -#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || \ - (((ip6addr)->addr[0] == 0) && \ - ((ip6addr)->addr[1] == 0) && \ - ((ip6addr)->addr[2] == 0) && \ - ((ip6addr)->addr[3] == 0))) - - -#define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL)) - -#define ip6_addr_islinklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfe800000UL)) - -#define ip6_addr_issitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfec00000UL)) - -#define ip6_addr_isuniquelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xfe000000UL)) == PP_HTONL(0xfc000000UL)) - -#define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) -#define ip6_addr_multicast_transient_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00100000UL)) -#define ip6_addr_multicast_prefix_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00200000UL)) -#define ip6_addr_multicast_rendezvous_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00400000UL)) -#define ip6_addr_multicast_scope(ip6addr) ((htonl((ip6addr)->addr[0]) >> 16) & 0xf) -#define IP6_MULTICAST_SCOPE_RESERVED 0x0 -#define IP6_MULTICAST_SCOPE_RESERVED0 0x0 -#define IP6_MULTICAST_SCOPE_INTERFACE_LOCAL 0x1 -#define IP6_MULTICAST_SCOPE_LINK_LOCAL 0x2 -#define IP6_MULTICAST_SCOPE_RESERVED3 0x3 -#define IP6_MULTICAST_SCOPE_ADMIN_LOCAL 0x4 -#define IP6_MULTICAST_SCOPE_SITE_LOCAL 0x5 -#define IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL 0x8 -#define IP6_MULTICAST_SCOPE_GLOBAL 0xe -#define IP6_MULTICAST_SCOPE_RESERVEDF 0xf -#define ip6_addr_ismulticast_iflocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff010000UL)) -#define ip6_addr_ismulticast_linklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff020000UL)) -#define ip6_addr_ismulticast_adminlocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff040000UL)) -#define ip6_addr_ismulticast_sitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff050000UL)) -#define ip6_addr_ismulticast_orglocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff080000UL)) -#define ip6_addr_ismulticast_global(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff0e0000UL)) - -/* TODO define get/set for well-know multicast addresses, e.g. ff02::1 */ -#define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) - -#define ip6_addr_isallnodes_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) -#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) - -#define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000002UL))) -#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000002UL);}while(0) - -#define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ - (((ip6addr)->addr[3] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) ) - -#define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \ - (ip6addr)->addr[3] = htonl(0xff000000UL | (htonl(if_id) & 0x00ffffffUL));}while(0) - -#define ip6_addr_cmp_solicitednode(ip6addr, sn_addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0) && \ - ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ - ((ip6addr)->addr[3] == htonl(0xff000000UL | (htonl((sn_addr)->addr[3]) & 0x00ffffffUL)))) - -/* IPv6 address states. */ -#define IP6_ADDR_INVALID 0x00 -#define IP6_ADDR_TENTATIVE 0x08 -#define IP6_ADDR_TENTATIVE_1 0x09 /* 1 probe sent */ -#define IP6_ADDR_TENTATIVE_2 0x0a /* 2 probes sent */ -#define IP6_ADDR_TENTATIVE_3 0x0b /* 3 probes sent */ -#define IP6_ADDR_TENTATIVE_4 0x0c /* 4 probes sent */ -#define IP6_ADDR_TENTATIVE_5 0x0d /* 5 probes sent */ -#define IP6_ADDR_TENTATIVE_6 0x0e /* 6 probes sent */ -#define IP6_ADDR_TENTATIVE_7 0x0f /* 7 probes sent */ -#define IP6_ADDR_VALID 0x10 -#define IP6_ADDR_PREFERRED 0x30 -#define IP6_ADDR_DEPRECATED 0x50 - -#define ip6_addr_isinvalid(addr_state) (addr_state == IP6_ADDR_INVALID) -#define ip6_addr_istentative(addr_state) (addr_state & IP6_ADDR_TENTATIVE) -#define ip6_addr_isvalid(addr_state) (addr_state & IP6_ADDR_VALID) /* Include valid, preferred, and deprecated. */ -#define ip6_addr_ispreferred(addr_state) (addr_state == IP6_ADDR_PREFERRED) -#define ip6_addr_isdeprecated(addr_state) (addr_state == IP6_ADDR_DEPRECATED) - -#define ip6_addr_debug_print(debug, ipaddr) \ - LWIP_DEBUGF(debug, ("%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F, \ - ipaddr != NULL ? IP6_ADDR_BLOCK1(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK2(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK3(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK4(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK5(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK6(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK7(ipaddr) : 0, \ - ipaddr != NULL ? IP6_ADDR_BLOCK8(ipaddr) : 0)) - -int ip6addr_aton(const char *cp, ip6_addr_t *addr); -/** returns ptr to static buffer; not reentrant! */ -char *ip6addr_ntoa(const ip6_addr_t *addr); -char *ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen); - - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* __LWIP_IP6_ADDR_H__ */ +/** + * @file + * + * IPv6 addresses. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * Structs and macros for handling IPv6 addresses. + * + * Please coordinate changes and requests with Ivan Delamer + * + */ +#ifndef __LWIP_IP6_ADDR_H__ +#define __LWIP_IP6_ADDR_H__ + +#include "lwip/opt.h" + +#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* This is the aligned version of ip6_addr_t, + used as local variable, on the stack, etc. */ +struct ip6_addr { + u32_t addr[4]; +}; + +/* This is the packed version of ip6_addr_t, + used in network headers that are itself packed */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_addr_packed { + PACK_STRUCT_FIELD(u32_t addr[4]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** ip6_addr_t uses a struct for convenience only, so that the same defines can + * operate both on ip6_addr_t as well as on ip6_addr_p_t. */ +typedef struct ip6_addr ip6_addr_t; +typedef struct ip6_addr_packed ip6_addr_p_t; + + +/** IP6_ADDR_ANY can be used as a fixed IPv6 address + * for the wildcard + */ +extern const ip6_addr_t ip6_addr_any; +#define IP6_ADDR_ANY ((ip6_addr_t *)&ip6_addr_any) + + + + +#if BYTE_ORDER == BIG_ENDIAN +/** Set an IPv6 partial address given by byte-parts. */ +#define IP6_ADDR(ip6addr, index, a,b,c,d) \ + (ip6addr)->addr[index] = ((u32_t)((a) & 0xff) << 24) | \ + ((u32_t)((b) & 0xff) << 16) | \ + ((u32_t)((c) & 0xff) << 8) | \ + (u32_t)((d) & 0xff) +#else +/** Set an IPv6 partial address given by byte-parts. +Little-endian version, stored in network order (no htonl). */ +#define IP6_ADDR(ip6addr, index, a,b,c,d) \ + (ip6addr)->addr[index] = ((u32_t)((d) & 0xff) << 24) | \ + ((u32_t)((c) & 0xff) << 16) | \ + ((u32_t)((b) & 0xff) << 8) | \ + (u32_t)((a) & 0xff) +#endif + +/** Access address in 16-bit block */ +#define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)(htonl((ip6addr)->addr[0]) >> 16) & 0xffff) +#define IP6_ADDR_BLOCK2(ip6addr) ((u16_t)(htonl((ip6addr)->addr[0])) & 0xffff) +#define IP6_ADDR_BLOCK3(ip6addr) ((u16_t)(htonl((ip6addr)->addr[1]) >> 16) & 0xffff) +#define IP6_ADDR_BLOCK4(ip6addr) ((u16_t)(htonl((ip6addr)->addr[1])) & 0xffff) +#define IP6_ADDR_BLOCK5(ip6addr) ((u16_t)(htonl((ip6addr)->addr[2]) >> 16) & 0xffff) +#define IP6_ADDR_BLOCK6(ip6addr) ((u16_t)(htonl((ip6addr)->addr[2])) & 0xffff) +#define IP6_ADDR_BLOCK7(ip6addr) ((u16_t)(htonl((ip6addr)->addr[3]) >> 16) & 0xffff) +#define IP6_ADDR_BLOCK8(ip6addr) ((u16_t)(htonl((ip6addr)->addr[3])) & 0xffff) + +/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */ +#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \ + (dest).addr[1] = (src).addr[1]; \ + (dest).addr[2] = (src).addr[2]; \ + (dest).addr[3] = (src).addr[3];}while(0) +/** Safely copy one IPv6 address to another (src may be NULL) */ +#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \ + (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \ + (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \ + (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0) + +/** Set complete address to zero */ +#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = 0; \ + (ip6addr)->addr[3] = 0;}while(0) + +/** Set address to ipv6 'any' (no need for htonl()) */ +#define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr) +/** Set address to ipv6 loopback address */ +#define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = 0; \ + (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) +/** Safely copy one IPv6 address to another and change byte order + * from host- to network-order. */ +#define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : htonl((src)->addr[0]); \ + (dest)->addr[1] = (src) == NULL ? 0 : htonl((src)->addr[1]); \ + (dest)->addr[2] = (src) == NULL ? 0 : htonl((src)->addr[2]); \ + (dest)->addr[3] = (src) == NULL ? 0 : htonl((src)->addr[3]);}while(0) + + + +/** + * Determine if two IPv6 address are on the same network. + * + * @arg addr1 IPv6 address 1 + * @arg addr2 IPv6 address 2 + * @return !0 if the network identifiers of both address match + */ +#define ip6_addr_netcmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ + ((addr1)->addr[1] == (addr2)->addr[1])) + +#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ + ((addr1)->addr[1] == (addr2)->addr[1]) && \ + ((addr1)->addr[2] == (addr2)->addr[2]) && \ + ((addr1)->addr[3] == (addr2)->addr[3])) + +#define ip6_get_subnet_id(ip6addr) (htonl((ip6addr)->addr[2]) & 0x0000ffffUL) + +#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || \ + (((ip6addr)->addr[0] == 0) && \ + ((ip6addr)->addr[1] == 0) && \ + ((ip6addr)->addr[2] == 0) && \ + ((ip6addr)->addr[3] == 0))) + + +#define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL)) + +#define ip6_addr_islinklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfe800000UL)) + +#define ip6_addr_issitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfec00000UL)) + +#define ip6_addr_isuniquelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xfe000000UL)) == PP_HTONL(0xfc000000UL)) + +#define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) +#define ip6_addr_multicast_transient_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00100000UL)) +#define ip6_addr_multicast_prefix_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00200000UL)) +#define ip6_addr_multicast_rendezvous_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00400000UL)) +#define ip6_addr_multicast_scope(ip6addr) ((htonl((ip6addr)->addr[0]) >> 16) & 0xf) +#define IP6_MULTICAST_SCOPE_RESERVED 0x0 +#define IP6_MULTICAST_SCOPE_RESERVED0 0x0 +#define IP6_MULTICAST_SCOPE_INTERFACE_LOCAL 0x1 +#define IP6_MULTICAST_SCOPE_LINK_LOCAL 0x2 +#define IP6_MULTICAST_SCOPE_RESERVED3 0x3 +#define IP6_MULTICAST_SCOPE_ADMIN_LOCAL 0x4 +#define IP6_MULTICAST_SCOPE_SITE_LOCAL 0x5 +#define IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL 0x8 +#define IP6_MULTICAST_SCOPE_GLOBAL 0xe +#define IP6_MULTICAST_SCOPE_RESERVEDF 0xf +#define ip6_addr_ismulticast_iflocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff010000UL)) +#define ip6_addr_ismulticast_linklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff020000UL)) +#define ip6_addr_ismulticast_adminlocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff040000UL)) +#define ip6_addr_ismulticast_sitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff050000UL)) +#define ip6_addr_ismulticast_orglocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff080000UL)) +#define ip6_addr_ismulticast_global(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff0e0000UL)) + +/* TODO define get/set for well-know multicast addresses, e.g. ff02::1 */ +#define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \ + ((ip6addr)->addr[1] == 0UL) && \ + ((ip6addr)->addr[2] == 0UL) && \ + ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) + +#define ip6_addr_isallnodes_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ + ((ip6addr)->addr[1] == 0UL) && \ + ((ip6addr)->addr[2] == 0UL) && \ + ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) +#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = 0; \ + (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) + +#define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ + ((ip6addr)->addr[1] == 0UL) && \ + ((ip6addr)->addr[2] == 0UL) && \ + ((ip6addr)->addr[3] == PP_HTONL(0x00000002UL))) +#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = 0; \ + (ip6addr)->addr[3] = PP_HTONL(0x00000002UL);}while(0) + +#define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ + ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ + (((ip6addr)->addr[3] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) ) + +#define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \ + (ip6addr)->addr[3] = htonl(0xff000000UL | (htonl(if_id) & 0x00ffffffUL));}while(0) + +#define ip6_addr_cmp_solicitednode(ip6addr, sn_addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ + ((ip6addr)->addr[1] == 0) && \ + ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ + ((ip6addr)->addr[3] == htonl(0xff000000UL | (htonl((sn_addr)->addr[3]) & 0x00ffffffUL)))) + +/* IPv6 address states. */ +#define IP6_ADDR_INVALID 0x00 +#define IP6_ADDR_TENTATIVE 0x08 +#define IP6_ADDR_TENTATIVE_1 0x09 /* 1 probe sent */ +#define IP6_ADDR_TENTATIVE_2 0x0a /* 2 probes sent */ +#define IP6_ADDR_TENTATIVE_3 0x0b /* 3 probes sent */ +#define IP6_ADDR_TENTATIVE_4 0x0c /* 4 probes sent */ +#define IP6_ADDR_TENTATIVE_5 0x0d /* 5 probes sent */ +#define IP6_ADDR_TENTATIVE_6 0x0e /* 6 probes sent */ +#define IP6_ADDR_TENTATIVE_7 0x0f /* 7 probes sent */ +#define IP6_ADDR_VALID 0x10 +#define IP6_ADDR_PREFERRED 0x30 +#define IP6_ADDR_DEPRECATED 0x50 + +#define ip6_addr_isinvalid(addr_state) (addr_state == IP6_ADDR_INVALID) +#define ip6_addr_istentative(addr_state) (addr_state & IP6_ADDR_TENTATIVE) +#define ip6_addr_isvalid(addr_state) (addr_state & IP6_ADDR_VALID) /* Include valid, preferred, and deprecated. */ +#define ip6_addr_ispreferred(addr_state) (addr_state == IP6_ADDR_PREFERRED) +#define ip6_addr_isdeprecated(addr_state) (addr_state == IP6_ADDR_DEPRECATED) + +#define ip6_addr_debug_print(debug, ipaddr) \ + LWIP_DEBUGF(debug, ("%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F, \ + ipaddr != NULL ? IP6_ADDR_BLOCK1(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK2(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK3(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK4(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK5(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK6(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK7(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK8(ipaddr) : 0)) + +int ip6addr_aton(const char *cp, ip6_addr_t *addr); +/** returns ptr to static buffer; not reentrant! */ +char *ip6addr_ntoa(const ip6_addr_t *addr); +char *ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen); + + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6 */ + +#endif /* __LWIP_IP6_ADDR_H__ */ diff --git a/include/lwip/ipv6/lwip/ip6_frag.h b/include/lwip/ipv6/lwip/ip6_frag.h index 53c2eeb3..75898b8f 100644 --- a/include/lwip/ipv6/lwip/ip6_frag.h +++ b/include/lwip/ipv6/lwip/ip6_frag.h @@ -1,102 +1,102 @@ -/** - * @file - * - * IPv6 fragmentation and reassembly. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef __LWIP_IP6_FRAG_H__ -#define __LWIP_IP6_FRAG_H__ - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ - -/* The IPv6 reassembly timer interval in milliseconds. */ -#define IP6_REASS_TMR_INTERVAL 1000 - -/* IPv6 reassembly helper struct. - * This is exported because memp needs to know the size. - */ -struct ip6_reassdata { - struct ip6_reassdata *next; - struct pbuf *p; - struct ip6_hdr * iphdr; - u32_t identification; - u16_t datagram_len; - u8_t nexth; - u8_t timer; -}; - -#define ip6_reass_init() /* Compatibility define */ -void ip6_reass_tmr(void); -struct pbuf * ip6_reass(struct pbuf *p); - -#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_FRAG /* don't build if not configured for use in lwipopts.h */ - -/** A custom pbuf that holds a reference to another pbuf, which is freed - * when this custom pbuf is freed. This is used to create a custom PBUF_REF - * that points into the original pbuf. */ -#ifndef __LWIP_PBUF_CUSTOM_REF__ -#define __LWIP_PBUF_CUSTOM_REF__ -struct pbuf_custom_ref { - /** 'base class' */ - struct pbuf_custom pc; - /** pointer to the original pbuf that is referenced */ - struct pbuf *original; -}; -#endif /* __LWIP_PBUF_CUSTOM_REF__ */ - -err_t ip6_frag(struct pbuf *p, struct netif *netif, ip6_addr_t *dest); - -#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP6_FRAG_H__ */ +/** + * @file + * + * IPv6 fragmentation and reassembly. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ +#ifndef __LWIP_IP6_FRAG_H__ +#define __LWIP_IP6_FRAG_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip6_addr.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ + +/* The IPv6 reassembly timer interval in milliseconds. */ +#define IP6_REASS_TMR_INTERVAL 1000 + +/* IPv6 reassembly helper struct. + * This is exported because memp needs to know the size. + */ +struct ip6_reassdata { + struct ip6_reassdata *next; + struct pbuf *p; + struct ip6_hdr * iphdr; + u32_t identification; + u16_t datagram_len; + u8_t nexth; + u8_t timer; +}; + +#define ip6_reass_init() /* Compatibility define */ +void ip6_reass_tmr(void); +struct pbuf * ip6_reass(struct pbuf *p); + +#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ + +#if LWIP_IPV6 && LWIP_IPV6_FRAG /* don't build if not configured for use in lwipopts.h */ + +/** A custom pbuf that holds a reference to another pbuf, which is freed + * when this custom pbuf is freed. This is used to create a custom PBUF_REF + * that points into the original pbuf. */ +#ifndef __LWIP_PBUF_CUSTOM_REF__ +#define __LWIP_PBUF_CUSTOM_REF__ +struct pbuf_custom_ref { + /** 'base class' */ + struct pbuf_custom pc; + /** pointer to the original pbuf that is referenced */ + struct pbuf *original; +}; +#endif /* __LWIP_PBUF_CUSTOM_REF__ */ + +err_t ip6_frag(struct pbuf *p, struct netif *netif, ip6_addr_t *dest); + +#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP6_FRAG_H__ */ diff --git a/include/lwip/ipv6/lwip/mld6.h b/include/lwip/ipv6/lwip/mld6.h index 963f96cb..abd86e55 100644 --- a/include/lwip/ipv6/lwip/mld6.h +++ b/include/lwip/ipv6/lwip/mld6.h @@ -1,118 +1,118 @@ -/** - * @file - * - * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. - * No support for MLDv2. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef __LWIP_MLD6_H__ -#define __LWIP_MLD6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6_MLD && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -struct mld_group { - /** next link */ - struct mld_group *next; - /** interface on which the group is active */ - struct netif *netif; - /** multicast address */ - ip6_addr_t group_address; - /** signifies we were the last person to report */ - u8_t last_reporter_flag; - /** current state of the group */ - u8_t group_state; - /** timer for reporting */ - u16_t timer; - /** counter of simultaneous uses */ - u8_t use; -}; - -/** Multicast listener report/query/done message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct mld_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t max_resp_delay); - PACK_STRUCT_FIELD(u16_t reserved); - PACK_STRUCT_FIELD(ip6_addr_p_t multicast_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define MLD6_TMR_INTERVAL 100 /* Milliseconds */ - -/* MAC Filter Actions, these are passed to a netif's - * mld_mac_filter callback function. */ -#define MLD6_DEL_MAC_FILTER 0 -#define MLD6_ADD_MAC_FILTER 1 - - -#define mld6_init() /* TODO should we init tables? */ -err_t mld6_stop(struct netif *netif); -void mld6_report_groups(struct netif *netif); -void mld6_tmr(void); -struct mld_group *mld6_lookfor_group(struct netif *ifp, ip6_addr_t *addr); -void mld6_input(struct pbuf *p, struct netif *inp); -err_t mld6_joingroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr); -err_t mld6_leavegroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr); - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6_MLD && LWIP_IPV6 */ - -#endif /* __LWIP_MLD6_H__ */ +/** + * @file + * + * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. + * No support for MLDv2. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#ifndef __LWIP_MLD6_H__ +#define __LWIP_MLD6_H__ + +#include "lwip/opt.h" + +#if LWIP_IPV6_MLD && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/netif.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +struct mld_group { + /** next link */ + struct mld_group *next; + /** interface on which the group is active */ + struct netif *netif; + /** multicast address */ + ip6_addr_t group_address; + /** signifies we were the last person to report */ + u8_t last_reporter_flag; + /** current state of the group */ + u8_t group_state; + /** timer for reporting */ + u16_t timer; + /** counter of simultaneous uses */ + u8_t use; +}; + +/** Multicast listener report/query/done message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct mld_header { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t max_resp_delay); + PACK_STRUCT_FIELD(u16_t reserved); + PACK_STRUCT_FIELD(ip6_addr_p_t multicast_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define MLD6_TMR_INTERVAL 100 /* Milliseconds */ + +/* MAC Filter Actions, these are passed to a netif's + * mld_mac_filter callback function. */ +#define MLD6_DEL_MAC_FILTER 0 +#define MLD6_ADD_MAC_FILTER 1 + + +#define mld6_init() /* TODO should we init tables? */ +err_t mld6_stop(struct netif *netif); +void mld6_report_groups(struct netif *netif); +void mld6_tmr(void); +struct mld_group *mld6_lookfor_group(struct netif *ifp, ip6_addr_t *addr); +void mld6_input(struct pbuf *p, struct netif *inp); +err_t mld6_joingroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr); +err_t mld6_leavegroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6_MLD && LWIP_IPV6 */ + +#endif /* __LWIP_MLD6_H__ */ diff --git a/include/lwip/ipv6/lwip/nd6.h b/include/lwip/ipv6/lwip/nd6.h index 49749331..28636e89 100644 --- a/include/lwip/ipv6/lwip/nd6.h +++ b/include/lwip/ipv6/lwip/nd6.h @@ -1,369 +1,369 @@ -/** - * @file - * - * Neighbor discovery and stateless address autoconfiguration for IPv6. - * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - * (Address autoconfiguration). - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef __LWIP_ND6_H__ -#define __LWIP_ND6_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Struct for tables. */ -struct nd6_neighbor_cache_entry { - ip6_addr_t next_hop_address; - struct netif * netif; - u8_t lladdr[NETIF_MAX_HWADDR_LEN]; - /*u32_t pmtu;*/ -#if LWIP_ND6_QUEUEING - /** Pointer to queue of pending outgoing packets on this entry. */ - struct nd6_q_entry *q; -#else /* LWIP_ND6_QUEUEING */ - /** Pointer to a single pending outgoing packet on this entry. */ - struct pbuf *q; -#endif /* LWIP_ND6_QUEUEING */ - u8_t state; - u8_t isrouter; - union { - u32_t reachable_time; - u32_t delay_time; - u32_t probes_sent; - u32_t stale_time; - } counter; -}; - -struct nd6_destination_cache_entry { - ip6_addr_t destination_addr; - ip6_addr_t next_hop_addr; - u32_t pmtu; - u32_t age; -}; - -struct nd6_prefix_list_entry { - ip6_addr_t prefix; - struct netif * netif; - u32_t invalidation_timer; -#if LWIP_IPV6_AUTOCONFIG - u8_t flags; -#define ND6_PREFIX_AUTOCONFIG_AUTONOMOUS 0x01 -#define ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED 0x02 -#define ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE 0x04 -#endif /* LWIP_IPV6_AUTOCONFIG */ -}; - -struct nd6_router_list_entry { - struct nd6_neighbor_cache_entry * neighbor_entry; - u32_t invalidation_timer; - u8_t flags; -}; - - -enum nd6_neighbor_cache_entry_state { - ND6_NO_ENTRY = 0, - ND6_INCOMPLETE, - ND6_REACHABLE, - ND6_STALE, - ND6_DELAY, - ND6_PROBE -}; - -#if LWIP_ND6_QUEUEING -/** struct for queueing outgoing packets for unknown address - * defined here to be accessed by memp.h - */ -struct nd6_q_entry { - struct nd6_q_entry *next; - struct pbuf *p; -}; -#endif /* LWIP_ND6_QUEUEING */ - -/** Neighbor solicitation message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ns_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - PACK_STRUCT_FIELD(ip6_addr_p_t target_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Neighbor advertisement message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct na_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u8_t flags); - PACK_STRUCT_FIELD(u8_t reserved[3]); - PACK_STRUCT_FIELD(ip6_addr_p_t target_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define ND6_FLAG_ROUTER (0x80) -#define ND6_FLAG_SOLICITED (0x40) -#define ND6_FLAG_OVERRIDE (0x20) - -/** Router solicitation message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct rs_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Router advertisement message header. */ -#define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80) -#define ND6_RA_FLAG_OTHER_STATEFUL_CONFIG (0x40) -#define ND6_RA_FLAG_HOME_AGENT (0x20) -#define ND6_RA_PREFERENCE_MASK (0x18) -#define ND6_RA_PREFERENCE_HIGH (0x08) -#define ND6_RA_PREFERENCE_MEDIUM (0x00) -#define ND6_RA_PREFERENCE_LOW (0x18) -#define ND6_RA_PREFERENCE_DISABLED (0x10) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ra_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u8_t current_hop_limit); - PACK_STRUCT_FIELD(u8_t flags); - PACK_STRUCT_FIELD(u16_t router_lifetime); - PACK_STRUCT_FIELD(u32_t reachable_time); - PACK_STRUCT_FIELD(u32_t retrans_timer); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Redirect message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct redirect_header { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - PACK_STRUCT_FIELD(ip6_addr_p_t target_address); - PACK_STRUCT_FIELD(ip6_addr_p_t destination_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Link-layer address option. */ -#define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01) -#define ND6_OPTION_TYPE_TARGET_LLADDR (0x02) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct lladdr_option { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t length); - PACK_STRUCT_FIELD(u8_t addr[NETIF_MAX_HWADDR_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Prefix information option. */ -#define ND6_OPTION_TYPE_PREFIX_INFO (0x03) -#define ND6_PREFIX_FLAG_ON_LINK (0x80) -#define ND6_PREFIX_FLAG_AUTONOMOUS (0x40) -#define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20) -#define ND6_PREFIX_FLAG_SITE_PREFIX (0x10) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct prefix_option { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t length); - PACK_STRUCT_FIELD(u8_t prefix_length); - PACK_STRUCT_FIELD(u8_t flags); - PACK_STRUCT_FIELD(u32_t valid_lifetime); - PACK_STRUCT_FIELD(u32_t preferred_lifetime); - PACK_STRUCT_FIELD(u8_t reserved2[3]); - PACK_STRUCT_FIELD(u8_t site_prefix_length); - PACK_STRUCT_FIELD(ip6_addr_p_t prefix); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Redirected header option. */ -#define ND6_OPTION_TYPE_REDIR_HDR (0x04) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct redirected_header_option { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t length); - PACK_STRUCT_FIELD(u8_t reserved[6]); - /* Portion of redirected packet follows. */ - /* PACK_STRUCT_FIELD(u8_t redirected[8]); */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** MTU option. */ -#define ND6_OPTION_TYPE_MTU (0x05) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct mtu_option { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t length); - PACK_STRUCT_FIELD(u16_t reserved); - PACK_STRUCT_FIELD(u32_t mtu); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Route information option. */ -#define ND6_OPTION_TYPE_ROUTE_INFO (24) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct route_option { - PACK_STRUCT_FIELD(u8_t type); - PACK_STRUCT_FIELD(u8_t length); - PACK_STRUCT_FIELD(u8_t prefix_length); - PACK_STRUCT_FIELD(u8_t preference); - PACK_STRUCT_FIELD(u32_t route_lifetime); - PACK_STRUCT_FIELD(ip6_addr_p_t prefix); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* the possible states of an IP address */ -#define IP6_ADDRESS_STATE_INVALID (0) -#define IP6_ADDRESS_STATE_VALID (0x4) -#define IP6_ADDRESS_STATE_PREFERRED (0x5) /* includes valid */ -#define IP6_ADDRESS_STATE_DEPRECATED (0x6) /* includes valid */ -#define IP6_ADDRESS_STATE_TENTATIV (0x8) - -/** 1 second period */ -#define ND6_TMR_INTERVAL 1000 - -/* Router tables. */ -/* TODO make these static? and entries accessible through API? */ -extern struct nd6_neighbor_cache_entry neighbor_cache[]; -extern struct nd6_destination_cache_entry destination_cache[]; -extern struct nd6_prefix_list_entry prefix_list[]; -extern struct nd6_router_list_entry default_router_list[]; - -/* Default values, can be updated by a RA message. */ -extern u32_t reachable_time; -extern u32_t retrans_timer; - -#define nd6_init() /* TODO should we init tables? */ -void nd6_tmr(void); -void nd6_input(struct pbuf *p, struct netif *inp); -s8_t nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif); -s8_t nd6_select_router(ip6_addr_t * ip6addr, struct netif * netif); -u16_t nd6_get_destination_mtu(ip6_addr_t * ip6addr, struct netif * netif); -err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf * p); -#if LWIP_ND6_TCP_REACHABILITY_HINTS -void nd6_reachability_hint(ip6_addr_t * ip6addr); -#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* __LWIP_ND6_H__ */ +/** + * @file + * + * Neighbor discovery and stateless address autoconfiguration for IPv6. + * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 + * (Address autoconfiguration). + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#ifndef __LWIP_ND6_H__ +#define __LWIP_ND6_H__ + +#include "lwip/opt.h" + +#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/netif.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Struct for tables. */ +struct nd6_neighbor_cache_entry { + ip6_addr_t next_hop_address; + struct netif * netif; + u8_t lladdr[NETIF_MAX_HWADDR_LEN]; + /*u32_t pmtu;*/ +#if LWIP_ND6_QUEUEING + /** Pointer to queue of pending outgoing packets on this entry. */ + struct nd6_q_entry *q; +#else /* LWIP_ND6_QUEUEING */ + /** Pointer to a single pending outgoing packet on this entry. */ + struct pbuf *q; +#endif /* LWIP_ND6_QUEUEING */ + u8_t state; + u8_t isrouter; + union { + u32_t reachable_time; + u32_t delay_time; + u32_t probes_sent; + u32_t stale_time; + } counter; +}; + +struct nd6_destination_cache_entry { + ip6_addr_t destination_addr; + ip6_addr_t next_hop_addr; + u32_t pmtu; + u32_t age; +}; + +struct nd6_prefix_list_entry { + ip6_addr_t prefix; + struct netif * netif; + u32_t invalidation_timer; +#if LWIP_IPV6_AUTOCONFIG + u8_t flags; +#define ND6_PREFIX_AUTOCONFIG_AUTONOMOUS 0x01 +#define ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED 0x02 +#define ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE 0x04 +#endif /* LWIP_IPV6_AUTOCONFIG */ +}; + +struct nd6_router_list_entry { + struct nd6_neighbor_cache_entry * neighbor_entry; + u32_t invalidation_timer; + u8_t flags; +}; + + +enum nd6_neighbor_cache_entry_state { + ND6_NO_ENTRY = 0, + ND6_INCOMPLETE, + ND6_REACHABLE, + ND6_STALE, + ND6_DELAY, + ND6_PROBE +}; + +#if LWIP_ND6_QUEUEING +/** struct for queueing outgoing packets for unknown address + * defined here to be accessed by memp.h + */ +struct nd6_q_entry { + struct nd6_q_entry *next; + struct pbuf *p; +}; +#endif /* LWIP_ND6_QUEUEING */ + +/** Neighbor solicitation message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ns_header { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t reserved); + PACK_STRUCT_FIELD(ip6_addr_p_t target_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Neighbor advertisement message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct na_header { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u8_t flags); + PACK_STRUCT_FIELD(u8_t reserved[3]); + PACK_STRUCT_FIELD(ip6_addr_p_t target_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define ND6_FLAG_ROUTER (0x80) +#define ND6_FLAG_SOLICITED (0x40) +#define ND6_FLAG_OVERRIDE (0x20) + +/** Router solicitation message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct rs_header { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t reserved); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Router advertisement message header. */ +#define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80) +#define ND6_RA_FLAG_OTHER_STATEFUL_CONFIG (0x40) +#define ND6_RA_FLAG_HOME_AGENT (0x20) +#define ND6_RA_PREFERENCE_MASK (0x18) +#define ND6_RA_PREFERENCE_HIGH (0x08) +#define ND6_RA_PREFERENCE_MEDIUM (0x00) +#define ND6_RA_PREFERENCE_LOW (0x18) +#define ND6_RA_PREFERENCE_DISABLED (0x10) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ra_header { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u8_t current_hop_limit); + PACK_STRUCT_FIELD(u8_t flags); + PACK_STRUCT_FIELD(u16_t router_lifetime); + PACK_STRUCT_FIELD(u32_t reachable_time); + PACK_STRUCT_FIELD(u32_t retrans_timer); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Redirect message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct redirect_header { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t reserved); + PACK_STRUCT_FIELD(ip6_addr_p_t target_address); + PACK_STRUCT_FIELD(ip6_addr_p_t destination_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Link-layer address option. */ +#define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01) +#define ND6_OPTION_TYPE_TARGET_LLADDR (0x02) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct lladdr_option { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t length); + PACK_STRUCT_FIELD(u8_t addr[NETIF_MAX_HWADDR_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Prefix information option. */ +#define ND6_OPTION_TYPE_PREFIX_INFO (0x03) +#define ND6_PREFIX_FLAG_ON_LINK (0x80) +#define ND6_PREFIX_FLAG_AUTONOMOUS (0x40) +#define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20) +#define ND6_PREFIX_FLAG_SITE_PREFIX (0x10) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct prefix_option { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t length); + PACK_STRUCT_FIELD(u8_t prefix_length); + PACK_STRUCT_FIELD(u8_t flags); + PACK_STRUCT_FIELD(u32_t valid_lifetime); + PACK_STRUCT_FIELD(u32_t preferred_lifetime); + PACK_STRUCT_FIELD(u8_t reserved2[3]); + PACK_STRUCT_FIELD(u8_t site_prefix_length); + PACK_STRUCT_FIELD(ip6_addr_p_t prefix); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Redirected header option. */ +#define ND6_OPTION_TYPE_REDIR_HDR (0x04) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct redirected_header_option { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t length); + PACK_STRUCT_FIELD(u8_t reserved[6]); + /* Portion of redirected packet follows. */ + /* PACK_STRUCT_FIELD(u8_t redirected[8]); */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** MTU option. */ +#define ND6_OPTION_TYPE_MTU (0x05) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct mtu_option { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t length); + PACK_STRUCT_FIELD(u16_t reserved); + PACK_STRUCT_FIELD(u32_t mtu); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Route information option. */ +#define ND6_OPTION_TYPE_ROUTE_INFO (24) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct route_option { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t length); + PACK_STRUCT_FIELD(u8_t prefix_length); + PACK_STRUCT_FIELD(u8_t preference); + PACK_STRUCT_FIELD(u32_t route_lifetime); + PACK_STRUCT_FIELD(ip6_addr_p_t prefix); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* the possible states of an IP address */ +#define IP6_ADDRESS_STATE_INVALID (0) +#define IP6_ADDRESS_STATE_VALID (0x4) +#define IP6_ADDRESS_STATE_PREFERRED (0x5) /* includes valid */ +#define IP6_ADDRESS_STATE_DEPRECATED (0x6) /* includes valid */ +#define IP6_ADDRESS_STATE_TENTATIV (0x8) + +/** 1 second period */ +#define ND6_TMR_INTERVAL 1000 + +/* Router tables. */ +/* TODO make these static? and entries accessible through API? */ +extern struct nd6_neighbor_cache_entry neighbor_cache[]; +extern struct nd6_destination_cache_entry destination_cache[]; +extern struct nd6_prefix_list_entry prefix_list[]; +extern struct nd6_router_list_entry default_router_list[]; + +/* Default values, can be updated by a RA message. */ +extern u32_t reachable_time; +extern u32_t retrans_timer; + +#define nd6_init() /* TODO should we init tables? */ +void nd6_tmr(void); +void nd6_input(struct pbuf *p, struct netif *inp); +s8_t nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif); +s8_t nd6_select_router(ip6_addr_t * ip6addr, struct netif * netif); +u16_t nd6_get_destination_mtu(ip6_addr_t * ip6addr, struct netif * netif); +err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf * p); +#if LWIP_ND6_TCP_REACHABILITY_HINTS +void nd6_reachability_hint(ip6_addr_t * ip6addr); +#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6 */ + +#endif /* __LWIP_ND6_H__ */ diff --git a/include/lwip/lwip/api.h b/include/lwip/lwip/api.h index 08b7b1d2..ce45edd8 100644 --- a/include/lwip/lwip/api.h +++ b/include/lwip/lwip/api.h @@ -1,440 +1,440 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_API_H__ -#define __LWIP_API_H__ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include /* for size_t */ - -#include "lwip/netbuf.h" -#include "lwip/sys.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Throughout this file, IP addresses and port numbers are expected to be in - * the same byte order as in the corresponding pcb. - */ - -/* Flags for netconn_write (u8_t) */ -#define NETCONN_NOFLAG 0x00 -#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */ -#define NETCONN_COPY 0x01 -#define NETCONN_MORE 0x02 -#define NETCONN_DONTBLOCK 0x04 - -/* Flags for struct netconn.flags (u8_t) */ -/** TCP: when data passed to netconn_write doesn't fit into the send buffer, - this temporarily stores whether to wake up the original application task - if data couldn't be sent in the first try. */ -#define NETCONN_FLAG_WRITE_DELAYED 0x01 -/** Should this netconn avoid blocking? */ -#define NETCONN_FLAG_NON_BLOCKING 0x02 -/** Was the last connect action a non-blocking one? */ -#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04 -/** If this is set, a TCP netconn must call netconn_recved() to update - the TCP receive window (done automatically if not set). */ -#define NETCONN_FLAG_NO_AUTO_RECVED 0x08 -/** If a nonblocking write has been rejected before, poll_tcp needs to - check if the netconn is writable again */ -#define NETCONN_FLAG_CHECK_WRITESPACE 0x10 -#if LWIP_IPV6 -/** If this flag is set then only IPv6 communication is allowed on the - netconn. As per RFC#3493 this features defaults to OFF allowing - dual-stack usage by default. */ -#define NETCONN_FLAG_IPV6_V6ONLY 0x20 -#endif /* LWIP_IPV6 */ - - //***********Code for WIFI_BLOCK from upper************** -#define NETCONN_FLAG_RECV_HOLD 0x80 - - -/* Helpers to process several netconn_types by the same code */ -#define NETCONNTYPE_GROUP(t) ((t)&0xF0) -#define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0) -#if LWIP_IPV6 -#define NETCONN_TYPE_IPV6 0x08 -#define NETCONNTYPE_ISIPV6(t) ((t)&0x08) -#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF7) == NETCONN_UDPLITE) -#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF7) == NETCONN_UDPNOCHKSUM) -#else /* LWIP_IPV6 */ -#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE) -#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM) -#endif /* LWIP_IPV6 */ - -/** Protocol family and type of the netconn */ -enum netconn_type { - NETCONN_INVALID = 0, - /* NETCONN_TCP Group */ - NETCONN_TCP = 0x10, -#if LWIP_IPV6 - NETCONN_TCP_IPV6 = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */, -#endif /* LWIP_IPV6 */ - /* NETCONN_UDP Group */ - NETCONN_UDP = 0x20, - NETCONN_UDPLITE = 0x21, - NETCONN_UDPNOCHKSUM = 0x22, -#if LWIP_IPV6 - NETCONN_UDP_IPV6 = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */, - NETCONN_UDPLITE_IPV6 = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */, - NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */, -#endif /* LWIP_IPV6 */ - /* NETCONN_RAW Group */ - NETCONN_RAW = 0x40 -#if LWIP_IPV6 - , - NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */ -#endif /* LWIP_IPV6 */ -}; - -/** Current state of the netconn. Non-TCP netconns are always - * in state NETCONN_NONE! */ -enum netconn_state { - NETCONN_NONE, - NETCONN_WRITE, - NETCONN_LISTEN, - NETCONN_CONNECT, - NETCONN_CLOSE -}; - -/** Use to inform the callback function about changes */ -enum netconn_evt { - NETCONN_EVT_RCVPLUS, - NETCONN_EVT_RCVMINUS, - NETCONN_EVT_SENDPLUS, - NETCONN_EVT_SENDMINUS, - NETCONN_EVT_ERROR -}; - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -/** Used for netconn_join_leave_group() */ -enum netconn_igmp { - NETCONN_JOIN, - NETCONN_LEAVE -}; -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -/* forward-declare some structs to avoid to include their headers */ -struct ip_pcb; -struct tcp_pcb; -struct udp_pcb; -struct raw_pcb; -struct netconn; -struct api_msg_msg; - -/** A callback prototype to inform about events for a netconn */ -typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len); - -/** A netconn descriptor */ -struct netconn { - /** type of the netconn (TCP, UDP or RAW) */ - enum netconn_type type; - /** current state of the netconn */ - enum netconn_state state; - /** the lwIP internal protocol control block */ - union { - struct ip_pcb *ip; - struct tcp_pcb *tcp; - struct udp_pcb *udp; - struct raw_pcb *raw; - } pcb; - /** the last error this netconn had */ - err_t last_err; - /** sem that is used to synchroneously execute functions in the core context */ - sys_sem_t op_completed; // - sys_sem_t snd_op_completed; //only for snd semphore - sys_sem_t ioctrl_completed; //only for IO ctrl semphore - /** mbox where received packets are stored until they are fetched - by the netconn application thread (can grow quite big) */ - sys_mbox_t recvmbox; -#if LWIP_TCP - /** mbox where new connections are stored until processed - by the application thread */ - sys_mbox_t acceptmbox; -#endif /* LWIP_TCP */ - /** only used for socket layer */ -#if LWIP_SOCKET - int socket; -#endif /* LWIP_SOCKET */ -#if LWIP_SO_SNDTIMEO - /** timeout to wait for sending data (which means enqueueing data for sending - in internal buffers) */ - s32_t send_timeout; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVTIMEO - /** timeout to wait for new data to be received - (or connections to arrive for listening netconns) */ - int recv_timeout; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - /** maximum amount of bytes queued in recvmbox - not used for TCP: adjust TCP_WND instead! */ - int recv_bufsize; - /** number of bytes currently in recvmbox to be received, - tested against recv_bufsize to limit bytes on recvmbox - for UDP and RAW, used for FIONREAD */ - s16_t recv_avail; -#endif /* LWIP_SO_RCVBUF */ - /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */ - u8_t flags; -#if LWIP_TCP - //***********Code for WIFI_BLOCK from upper************** - u32_t recv_holded_buf_Len; - /** TCP: when data passed to netconn_write doesn't fit into the send buffer, - this temporarily stores how much is already sent. */ - size_t write_offset; - /** TCP: when data passed to netconn_write doesn't fit into the send buffer, - this temporarily stores the message. - Also used during connect and close. */ - struct api_msg_msg *current_msg; -#endif /* LWIP_TCP */ - /** A callback function that is informed about events for this netconn */ - netconn_callback callback; - -#if LWIP_SO_LINGER - /* add by DongHeng, to force to free TCP */ - s16_t linger; -#endif - -#ifdef SOCKETS_TCP_TRACE - u32_t recv_bytes[2]; - u32_t recv_bytes_err[2]; - - u32_t send_bytes[2]; - u32_t send_bytes_ok[2]; - u32_t send_bytes_nomem[2]; - -#define ADD_TCP_RECV_BYTES(s, b) \ -{ \ - if (s->recv_bytes[0] > 0xffff0000){ \ - s->recv_bytes[0] = b; \ - s->recv_bytes[1]++; \ - } else { \ - s->recv_bytes[0] += b; \ - } \ -} - -#define ADD_TCP_RECV_BYTES_ERR(s, b) \ -{ \ - if (s->recv_bytes_err[0] > 0xffff0000){ \ - s->recv_bytes_err[0] = b; \ - s->recv_bytes_err[1]++; \ - } else { \ - s->recv_bytes_err[0] += b; \ - } \ -} - -#define ADD_TCP_SEND_BYTES(s, b) \ -{ \ - if (s->send_bytes[0] > 0xffff0000){ \ - s->send_bytes[0] = b; \ - s->send_bytes[1]++; \ - } else { \ - s->send_bytes[0] += b; \ - } \ -} - -#define ADD_TCP_SEND_BYTES_OK(s, b) \ -{ \ - if (s->send_bytes_ok[0] > 0xffff0000){ \ - s->send_bytes_ok[0] = b; \ - s->send_bytes_ok[1]++; \ - } else { \ - s->send_bytes_ok[0] += b; \ - } \ -} - -#define ADD_TCP_SEND_BYTES_NOMEM(s, b) \ -{ \ - if (s->send_bytes_nomem[0] > 0xffff0000){ \ - s->send_bytes_nomem[0] = b; \ - s->send_bytes_nomem[1]++; \ - } else { \ - s->send_bytes_nomem[0] += b; \ - } \ -} - -#define ADD_TCP_RECV_BYTES_CLEAR(s) \ - (s)->recv_bytes[0] = (s)->recv_bytes[1] = 0; - -#define ADD_TCP_RECV_BYTES_ERR_CLEAR(s) \ - (s)->recv_bytes_err[0] = (s)->recv_bytes_err[1] = 0; - -#define ADD_TCP_SEND_BYTES_CLEAR(s) \ - (s)->send_bytes[0] = (s)->send_bytes[1] = 0; - -#define ADD_TCP_SEND_BYTES_OK_CLEAR(s) \ - (s)->send_bytes_ok[0] = (s)->send_bytes_ok[1] = 0; - -#define ADD_TCP_SEND_BYTES_NOMEM_CLEAR(s) \ - (s)->send_bytes_nomem[0] = (s)->send_bytes_nomem[1] = 0; - -#define ADD_TCP_RECV_BYTES_GET(s, b) \ - (b)[0] = (s)->recv_bytes[0]; (b)[1] = (s)->recv_bytes[1]; - -#define ADD_TCP_RECV_BYTES_ERR_GET(s, b) \ - (b)[0] = (s)->recv_bytes_err[0]; (b)[1] = (s)->recv_bytes_err[1]; - -#define ADD_TCP_SEND_BYTES_GET(s, b) \ - (b)[0] = (s)->send_bytes[0]; (b)[1] = (s)->send_bytes[1]; - -#define ADD_TCP_SEND_BYTES_OK_GET(s, b) \ - (b)[0] = (s)->send_bytes_ok[0]; (b)[1] = (s)->send_bytes_ok[1]; - -#define ADD_TCP_SEND_BYTES_NOMEM_GET(s, b) \ - (b)[0] = (s)->send_bytes_nomem[0]; (b)[1] = (s)->send_bytes_nomem[1]; - -#endif -}; - -/** Register an Network connection event */ -#define API_EVENT(c,e,l) if (c->callback) { \ - (*c->callback)(c, e, l); \ - } - -/** Set conn->last_err to err but don't overwrite fatal errors */ -#define NETCONN_SET_SAFE_ERR(conn, err) do { \ - SYS_ARCH_DECL_PROTECT(lev); \ - SYS_ARCH_PROTECT(lev); \ - if (!ERR_IS_FATAL((conn)->last_err)) { \ - (conn)->last_err = err; \ - } \ - SYS_ARCH_UNPROTECT(lev); \ -} while(0); - -/* Network connection functions: */ -#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL) -#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c) -struct -netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, - netconn_callback callback); -err_t netconn_delete(struct netconn *conn); -/** Get the type of a netconn (as enum netconn_type). */ -#define netconn_type(conn) (conn->type) - -err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr, - u16_t *port, u8_t local); -#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0) -#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1) - -err_t netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port); -err_t netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port); -err_t netconn_disconnect (struct netconn *conn); -err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); -#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG) -err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); -err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf); -err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf); -void netconn_recved(struct netconn *conn, u32_t length); -err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, - ip_addr_t *addr, u16_t port); -err_t netconn_send(struct netconn *conn, struct netbuf *buf); -err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, - u8_t apiflags, size_t *bytes_written); -#define netconn_write(conn, dataptr, size, apiflags) \ - netconn_write_partly(conn, dataptr, size, apiflags, NULL) -err_t netconn_close(struct netconn *conn); -err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx); - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -err_t netconn_join_leave_group(struct netconn *conn, ip_addr_t *multiaddr, - ip_addr_t *netif_addr, enum netconn_igmp join_or_leave); -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ -#if LWIP_DNS -err_t netconn_gethostbyname(const char *name, ip_addr_t *addr); -#endif /* LWIP_DNS */ -#if LWIP_IPV6 - -#define netconn_bind_ip6(conn, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ - netconn_bind(conn, ip6_2_ip(ip6addr), port) : ERR_VAL) -#define netconn_connect_ip6(conn, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ - netconn_connect(conn, ip6_2_ip(ip6addr), port) : ERR_VAL) -#define netconn_sendto_ip6(conn, buf, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ - netconn_sendto(conn, buf, ip6_2_ip(ip6addr), port) : ERR_VAL) -#if LWIP_IPV6_MLD -#define netconn_join_leave_group_ip6(conn, multiaddr, srcaddr, join_or_leave) (NETCONNTYPE_ISIPV6((conn)->type) ? \ - netconn_join_leave_group(conn, ip6_2_ip(multiaddr), ip6_2_ip(srcaddr), join_or_leave) :\ - ERR_VAL) -#endif /* LWIP_IPV6_MLD*/ -#endif /* LWIP_IPV6 */ - -#define netconn_err(conn) ((conn)->last_err) -#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) - -/** Set the blocking status of netconn calls (@todo: write/send is missing) */ -#define netconn_set_nonblocking(conn, val) do { if(val) { \ - (conn)->flags |= NETCONN_FLAG_NON_BLOCKING; \ -} else { \ - (conn)->flags &= ~ NETCONN_FLAG_NON_BLOCKING; }} while(0) -/** Get the blocking status of netconn calls (@todo: write/send is missing) */ -#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0) - -/** TCP: Set the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ -#define netconn_set_noautorecved(conn, val) do { if(val) { \ - (conn)->flags |= NETCONN_FLAG_NO_AUTO_RECVED; \ -} else { \ - (conn)->flags &= ~ NETCONN_FLAG_NO_AUTO_RECVED; }} while(0) -/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ -#define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0) - -#if LWIP_SO_SNDTIMEO -/** Set the send timeout in milliseconds */ -#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout)) -/** Get the send timeout in milliseconds */ -#define netconn_get_sendtimeout(conn) ((conn)->send_timeout) -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO -/** Set the receive timeout in milliseconds */ -#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout)) -/** Get the receive timeout in milliseconds */ -#define netconn_get_recvtimeout(conn) ((conn)->recv_timeout) -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF -/** Set the receive buffer in bytes */ -#define netconn_set_recvbufsize(conn, recvbufsize) ((conn)->recv_bufsize = (recvbufsize)) -/** Get the receive buffer in bytes */ -#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize) -#endif /* LWIP_SO_RCVBUF*/ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETCONN */ - -#endif /* __LWIP_API_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_API_H__ +#define __LWIP_API_H__ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/netbuf.h" +#include "lwip/sys.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Throughout this file, IP addresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ + +/* Flags for netconn_write (u8_t) */ +#define NETCONN_NOFLAG 0x00 +#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */ +#define NETCONN_COPY 0x01 +#define NETCONN_MORE 0x02 +#define NETCONN_DONTBLOCK 0x04 + +/* Flags for struct netconn.flags (u8_t) */ +/** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores whether to wake up the original application task + if data couldn't be sent in the first try. */ +#define NETCONN_FLAG_WRITE_DELAYED 0x01 +/** Should this netconn avoid blocking? */ +#define NETCONN_FLAG_NON_BLOCKING 0x02 +/** Was the last connect action a non-blocking one? */ +#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04 +/** If this is set, a TCP netconn must call netconn_recved() to update + the TCP receive window (done automatically if not set). */ +#define NETCONN_FLAG_NO_AUTO_RECVED 0x08 +/** If a nonblocking write has been rejected before, poll_tcp needs to + check if the netconn is writable again */ +#define NETCONN_FLAG_CHECK_WRITESPACE 0x10 +#if LWIP_IPV6 +/** If this flag is set then only IPv6 communication is allowed on the + netconn. As per RFC#3493 this features defaults to OFF allowing + dual-stack usage by default. */ +#define NETCONN_FLAG_IPV6_V6ONLY 0x20 +#endif /* LWIP_IPV6 */ + + //***********Code for WIFI_BLOCK from upper************** +#define NETCONN_FLAG_RECV_HOLD 0x80 + + +/* Helpers to process several netconn_types by the same code */ +#define NETCONNTYPE_GROUP(t) ((t)&0xF0) +#define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0) +#if LWIP_IPV6 +#define NETCONN_TYPE_IPV6 0x08 +#define NETCONNTYPE_ISIPV6(t) ((t)&0x08) +#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF7) == NETCONN_UDPLITE) +#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF7) == NETCONN_UDPNOCHKSUM) +#else /* LWIP_IPV6 */ +#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE) +#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM) +#endif /* LWIP_IPV6 */ + +/** Protocol family and type of the netconn */ +enum netconn_type { + NETCONN_INVALID = 0, + /* NETCONN_TCP Group */ + NETCONN_TCP = 0x10, +#if LWIP_IPV6 + NETCONN_TCP_IPV6 = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */, +#endif /* LWIP_IPV6 */ + /* NETCONN_UDP Group */ + NETCONN_UDP = 0x20, + NETCONN_UDPLITE = 0x21, + NETCONN_UDPNOCHKSUM = 0x22, +#if LWIP_IPV6 + NETCONN_UDP_IPV6 = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */, + NETCONN_UDPLITE_IPV6 = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */, + NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */, +#endif /* LWIP_IPV6 */ + /* NETCONN_RAW Group */ + NETCONN_RAW = 0x40 +#if LWIP_IPV6 + , + NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */ +#endif /* LWIP_IPV6 */ +}; + +/** Current state of the netconn. Non-TCP netconns are always + * in state NETCONN_NONE! */ +enum netconn_state { + NETCONN_NONE, + NETCONN_WRITE, + NETCONN_LISTEN, + NETCONN_CONNECT, + NETCONN_CLOSE +}; + +/** Use to inform the callback function about changes */ +enum netconn_evt { + NETCONN_EVT_RCVPLUS, + NETCONN_EVT_RCVMINUS, + NETCONN_EVT_SENDPLUS, + NETCONN_EVT_SENDMINUS, + NETCONN_EVT_ERROR +}; + +#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) +/** Used for netconn_join_leave_group() */ +enum netconn_igmp { + NETCONN_JOIN, + NETCONN_LEAVE +}; +#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + +/* forward-declare some structs to avoid to include their headers */ +struct ip_pcb; +struct tcp_pcb; +struct udp_pcb; +struct raw_pcb; +struct netconn; +struct api_msg_msg; + +/** A callback prototype to inform about events for a netconn */ +typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len); + +/** A netconn descriptor */ +struct netconn { + /** type of the netconn (TCP, UDP or RAW) */ + enum netconn_type type; + /** current state of the netconn */ + enum netconn_state state; + /** the lwIP internal protocol control block */ + union { + struct ip_pcb *ip; + struct tcp_pcb *tcp; + struct udp_pcb *udp; + struct raw_pcb *raw; + } pcb; + /** the last error this netconn had */ + err_t last_err; + /** sem that is used to synchroneously execute functions in the core context */ + sys_sem_t op_completed; // + sys_sem_t snd_op_completed; //only for snd semphore + sys_sem_t ioctrl_completed; //only for IO ctrl semphore + /** mbox where received packets are stored until they are fetched + by the netconn application thread (can grow quite big) */ + sys_mbox_t recvmbox; +#if LWIP_TCP + /** mbox where new connections are stored until processed + by the application thread */ + sys_mbox_t acceptmbox; +#endif /* LWIP_TCP */ + /** only used for socket layer */ +#if LWIP_SOCKET + int socket; +#endif /* LWIP_SOCKET */ +#if LWIP_SO_SNDTIMEO + /** timeout to wait for sending data (which means enqueueing data for sending + in internal buffers) */ + s32_t send_timeout; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVTIMEO + /** timeout to wait for new data to be received + (or connections to arrive for listening netconns) */ + int recv_timeout; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + /** maximum amount of bytes queued in recvmbox + not used for TCP: adjust TCP_WND instead! */ + int recv_bufsize; + /** number of bytes currently in recvmbox to be received, + tested against recv_bufsize to limit bytes on recvmbox + for UDP and RAW, used for FIONREAD */ + s16_t recv_avail; +#endif /* LWIP_SO_RCVBUF */ + /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */ + u8_t flags; +#if LWIP_TCP + //***********Code for WIFI_BLOCK from upper************** + u32_t recv_holded_buf_Len; + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores how much is already sent. */ + size_t write_offset; + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores the message. + Also used during connect and close. */ + struct api_msg_msg *current_msg; +#endif /* LWIP_TCP */ + /** A callback function that is informed about events for this netconn */ + netconn_callback callback; + +#if LWIP_SO_LINGER + /* add by DongHeng, to force to free TCP */ + s16_t linger; +#endif + +#ifdef SOCKETS_TCP_TRACE + u32_t recv_bytes[2]; + u32_t recv_bytes_err[2]; + + u32_t send_bytes[2]; + u32_t send_bytes_ok[2]; + u32_t send_bytes_nomem[2]; + +#define ADD_TCP_RECV_BYTES(s, b) \ +{ \ + if (s->recv_bytes[0] > 0xffff0000){ \ + s->recv_bytes[0] = b; \ + s->recv_bytes[1]++; \ + } else { \ + s->recv_bytes[0] += b; \ + } \ +} + +#define ADD_TCP_RECV_BYTES_ERR(s, b) \ +{ \ + if (s->recv_bytes_err[0] > 0xffff0000){ \ + s->recv_bytes_err[0] = b; \ + s->recv_bytes_err[1]++; \ + } else { \ + s->recv_bytes_err[0] += b; \ + } \ +} + +#define ADD_TCP_SEND_BYTES(s, b) \ +{ \ + if (s->send_bytes[0] > 0xffff0000){ \ + s->send_bytes[0] = b; \ + s->send_bytes[1]++; \ + } else { \ + s->send_bytes[0] += b; \ + } \ +} + +#define ADD_TCP_SEND_BYTES_OK(s, b) \ +{ \ + if (s->send_bytes_ok[0] > 0xffff0000){ \ + s->send_bytes_ok[0] = b; \ + s->send_bytes_ok[1]++; \ + } else { \ + s->send_bytes_ok[0] += b; \ + } \ +} + +#define ADD_TCP_SEND_BYTES_NOMEM(s, b) \ +{ \ + if (s->send_bytes_nomem[0] > 0xffff0000){ \ + s->send_bytes_nomem[0] = b; \ + s->send_bytes_nomem[1]++; \ + } else { \ + s->send_bytes_nomem[0] += b; \ + } \ +} + +#define ADD_TCP_RECV_BYTES_CLEAR(s) \ + (s)->recv_bytes[0] = (s)->recv_bytes[1] = 0; + +#define ADD_TCP_RECV_BYTES_ERR_CLEAR(s) \ + (s)->recv_bytes_err[0] = (s)->recv_bytes_err[1] = 0; + +#define ADD_TCP_SEND_BYTES_CLEAR(s) \ + (s)->send_bytes[0] = (s)->send_bytes[1] = 0; + +#define ADD_TCP_SEND_BYTES_OK_CLEAR(s) \ + (s)->send_bytes_ok[0] = (s)->send_bytes_ok[1] = 0; + +#define ADD_TCP_SEND_BYTES_NOMEM_CLEAR(s) \ + (s)->send_bytes_nomem[0] = (s)->send_bytes_nomem[1] = 0; + +#define ADD_TCP_RECV_BYTES_GET(s, b) \ + (b)[0] = (s)->recv_bytes[0]; (b)[1] = (s)->recv_bytes[1]; + +#define ADD_TCP_RECV_BYTES_ERR_GET(s, b) \ + (b)[0] = (s)->recv_bytes_err[0]; (b)[1] = (s)->recv_bytes_err[1]; + +#define ADD_TCP_SEND_BYTES_GET(s, b) \ + (b)[0] = (s)->send_bytes[0]; (b)[1] = (s)->send_bytes[1]; + +#define ADD_TCP_SEND_BYTES_OK_GET(s, b) \ + (b)[0] = (s)->send_bytes_ok[0]; (b)[1] = (s)->send_bytes_ok[1]; + +#define ADD_TCP_SEND_BYTES_NOMEM_GET(s, b) \ + (b)[0] = (s)->send_bytes_nomem[0]; (b)[1] = (s)->send_bytes_nomem[1]; + +#endif +}; + +/** Register an Network connection event */ +#define API_EVENT(c,e,l) if (c->callback) { \ + (*c->callback)(c, e, l); \ + } + +/** Set conn->last_err to err but don't overwrite fatal errors */ +#define NETCONN_SET_SAFE_ERR(conn, err) do { \ + SYS_ARCH_DECL_PROTECT(lev); \ + SYS_ARCH_PROTECT(lev); \ + if (!ERR_IS_FATAL((conn)->last_err)) { \ + (conn)->last_err = err; \ + } \ + SYS_ARCH_UNPROTECT(lev); \ +} while(0); + +/* Network connection functions: */ +#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL) +#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c) +struct +netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, + netconn_callback callback); +err_t netconn_delete(struct netconn *conn); +/** Get the type of a netconn (as enum netconn_type). */ +#define netconn_type(conn) (conn->type) + +err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr, + u16_t *port, u8_t local); +#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0) +#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1) + +err_t netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port); +err_t netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port); +err_t netconn_disconnect (struct netconn *conn); +err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); +#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG) +err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); +err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf); +err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf); +void netconn_recved(struct netconn *conn, u32_t length); +err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, + ip_addr_t *addr, u16_t port); +err_t netconn_send(struct netconn *conn, struct netbuf *buf); +err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, + u8_t apiflags, size_t *bytes_written); +#define netconn_write(conn, dataptr, size, apiflags) \ + netconn_write_partly(conn, dataptr, size, apiflags, NULL) +err_t netconn_close(struct netconn *conn); +err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx); + +#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) +err_t netconn_join_leave_group(struct netconn *conn, ip_addr_t *multiaddr, + ip_addr_t *netif_addr, enum netconn_igmp join_or_leave); +#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ +#if LWIP_DNS +err_t netconn_gethostbyname(const char *name, ip_addr_t *addr); +#endif /* LWIP_DNS */ +#if LWIP_IPV6 + +#define netconn_bind_ip6(conn, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_bind(conn, ip6_2_ip(ip6addr), port) : ERR_VAL) +#define netconn_connect_ip6(conn, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_connect(conn, ip6_2_ip(ip6addr), port) : ERR_VAL) +#define netconn_sendto_ip6(conn, buf, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_sendto(conn, buf, ip6_2_ip(ip6addr), port) : ERR_VAL) +#if LWIP_IPV6_MLD +#define netconn_join_leave_group_ip6(conn, multiaddr, srcaddr, join_or_leave) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_join_leave_group(conn, ip6_2_ip(multiaddr), ip6_2_ip(srcaddr), join_or_leave) :\ + ERR_VAL) +#endif /* LWIP_IPV6_MLD*/ +#endif /* LWIP_IPV6 */ + +#define netconn_err(conn) ((conn)->last_err) +#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) + +/** Set the blocking status of netconn calls (@todo: write/send is missing) */ +#define netconn_set_nonblocking(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_NON_BLOCKING; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_NON_BLOCKING; }} while(0) +/** Get the blocking status of netconn calls (@todo: write/send is missing) */ +#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0) + +/** TCP: Set the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ +#define netconn_set_noautorecved(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_NO_AUTO_RECVED; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_NO_AUTO_RECVED; }} while(0) +/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ +#define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0) + +#if LWIP_SO_SNDTIMEO +/** Set the send timeout in milliseconds */ +#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout)) +/** Get the send timeout in milliseconds */ +#define netconn_get_sendtimeout(conn) ((conn)->send_timeout) +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO +/** Set the receive timeout in milliseconds */ +#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout)) +/** Get the receive timeout in milliseconds */ +#define netconn_get_recvtimeout(conn) ((conn)->recv_timeout) +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF +/** Set the receive buffer in bytes */ +#define netconn_set_recvbufsize(conn, recvbufsize) ((conn)->recv_bufsize = (recvbufsize)) +/** Get the receive buffer in bytes */ +#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize) +#endif /* LWIP_SO_RCVBUF*/ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN */ + +#endif /* __LWIP_API_H__ */ diff --git a/include/lwip/lwip/api_msg.h b/include/lwip/lwip/api_msg.h index e5372aa6..8268036a 100644 --- a/include/lwip/lwip/api_msg.h +++ b/include/lwip/lwip/api_msg.h @@ -1,177 +1,177 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_API_MSG_H__ -#define __LWIP_API_MSG_H__ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include /* for size_t */ - -#include "lwip/ip_addr.h" -#include "lwip/err.h" -#include "lwip/sys.h" -#include "lwip/igmp.h" -#include "lwip/api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* For the netconn API, these values are use as a bitmask! */ -#define NETCONN_SHUT_RD 1 -#define NETCONN_SHUT_WR 2 -#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR) - -/* IP addresses and port numbers are expected to be in - * the same byte order as in the corresponding pcb. - */ -/** This struct includes everything that is necessary to execute a function - for a netconn in another thread context (mainly used to process netconns - in the tcpip_thread context to be thread safe). */ -struct api_msg_msg { - /** The netconn which to process - always needed: it includes the semaphore - which is used to block the application thread until the function finished. */ - struct netconn *conn; - /** The return value of the function executed in tcpip_thread. */ - err_t err; - /** Depending on the executed function, one of these union members is used */ - union { - /** used for lwip_netconn_do_send */ - struct netbuf *b; - /** used for lwip_netconn_do_newconn */ - struct { - u8_t proto; - } n; - /** used for lwip_netconn_do_bind and lwip_netconn_do_connect */ - struct { - ip_addr_t *ipaddr; - u16_t port; - } bc; - /** used for lwip_netconn_do_getaddr */ - struct { - ipX_addr_t *ipaddr; - u16_t *port; - u8_t local; - } ad; - /** used for lwip_netconn_do_write */ - struct { - const void *dataptr; - size_t len; - u8_t apiflags; -#if LWIP_SO_SNDTIMEO - u32_t time_started; -#endif /* LWIP_SO_SNDTIMEO */ - } w; - /** used for lwip_netconn_do_recv */ - struct { - u32_t len; - } r; - /** used for lwip_netconn_do_close (/shutdown) */ - struct { - u8_t shut; - } sd; -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) - /** used for lwip_netconn_do_join_leave_group */ - struct { - ipX_addr_t *multiaddr; - ipX_addr_t *netif_addr; - enum netconn_igmp join_or_leave; - } jl; -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ -#if TCP_LISTEN_BACKLOG - struct { - u8_t backlog; - } lb; -#endif /* TCP_LISTEN_BACKLOG */ - } msg; -}; - -/** This struct contains a function to execute in another thread context and - a struct api_msg_msg that serves as an argument for this function. - This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */ -struct api_msg { - /** function to execute in tcpip_thread context */ - void (* function)(struct api_msg_msg *msg); - /** arguments for this function */ - struct api_msg_msg msg; -}; - -#if LWIP_DNS -/** As lwip_netconn_do_gethostbyname requires more arguments but doesn't require a netconn, - it has its own struct (to avoid struct api_msg getting bigger than necessary). - lwip_netconn_do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg - (see netconn_gethostbyname). */ -struct dns_api_msg { - /** Hostname to query or dotted IP address string */ - const char *name; - /** Rhe resolved address is stored here */ - ip_addr_t *addr; - /** This semaphore is posted when the name is resolved, the application thread - should wait on it. */ - sys_sem_t *sem; - /** Errors are given back here */ - err_t *err; -}; -#endif /* LWIP_DNS */ - -void lwip_netconn_do_newconn ( struct api_msg_msg *msg); -void lwip_netconn_do_delconn ( struct api_msg_msg *msg); -void lwip_netconn_do_bind ( struct api_msg_msg *msg); -void lwip_netconn_do_connect ( struct api_msg_msg *msg); -void lwip_netconn_do_disconnect ( struct api_msg_msg *msg); -void lwip_netconn_do_listen ( struct api_msg_msg *msg); -void lwip_netconn_do_send ( struct api_msg_msg *msg); -void lwip_netconn_do_recv ( struct api_msg_msg *msg); -void lwip_netconn_do_write ( struct api_msg_msg *msg); -void lwip_netconn_do_getaddr ( struct api_msg_msg *msg); -void lwip_netconn_do_close ( struct api_msg_msg *msg); -void lwip_netconn_do_shutdown ( struct api_msg_msg *msg); -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -void lwip_netconn_do_join_leave_group( struct api_msg_msg *msg); -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -void lwip_netconn_do_gethostbyname(void *arg); -#endif /* LWIP_DNS */ - -struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback); -void netconn_free(struct netconn *conn); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETCONN */ - -#endif /* __LWIP_API_MSG_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_API_MSG_H__ +#define __LWIP_API_MSG_H__ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/sys.h" +#include "lwip/igmp.h" +#include "lwip/api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* For the netconn API, these values are use as a bitmask! */ +#define NETCONN_SHUT_RD 1 +#define NETCONN_SHUT_WR 2 +#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR) + +/* IP addresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ +/** This struct includes everything that is necessary to execute a function + for a netconn in another thread context (mainly used to process netconns + in the tcpip_thread context to be thread safe). */ +struct api_msg_msg { + /** The netconn which to process - always needed: it includes the semaphore + which is used to block the application thread until the function finished. */ + struct netconn *conn; + /** The return value of the function executed in tcpip_thread. */ + err_t err; + /** Depending on the executed function, one of these union members is used */ + union { + /** used for lwip_netconn_do_send */ + struct netbuf *b; + /** used for lwip_netconn_do_newconn */ + struct { + u8_t proto; + } n; + /** used for lwip_netconn_do_bind and lwip_netconn_do_connect */ + struct { + ip_addr_t *ipaddr; + u16_t port; + } bc; + /** used for lwip_netconn_do_getaddr */ + struct { + ipX_addr_t *ipaddr; + u16_t *port; + u8_t local; + } ad; + /** used for lwip_netconn_do_write */ + struct { + const void *dataptr; + size_t len; + u8_t apiflags; +#if LWIP_SO_SNDTIMEO + u32_t time_started; +#endif /* LWIP_SO_SNDTIMEO */ + } w; + /** used for lwip_netconn_do_recv */ + struct { + u32_t len; + } r; + /** used for lwip_netconn_do_close (/shutdown) */ + struct { + u8_t shut; + } sd; +#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) + /** used for lwip_netconn_do_join_leave_group */ + struct { + ipX_addr_t *multiaddr; + ipX_addr_t *netif_addr; + enum netconn_igmp join_or_leave; + } jl; +#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ +#if TCP_LISTEN_BACKLOG + struct { + u8_t backlog; + } lb; +#endif /* TCP_LISTEN_BACKLOG */ + } msg; +}; + +/** This struct contains a function to execute in another thread context and + a struct api_msg_msg that serves as an argument for this function. + This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */ +struct api_msg { + /** function to execute in tcpip_thread context */ + void (* function)(struct api_msg_msg *msg); + /** arguments for this function */ + struct api_msg_msg msg; +}; + +#if LWIP_DNS +/** As lwip_netconn_do_gethostbyname requires more arguments but doesn't require a netconn, + it has its own struct (to avoid struct api_msg getting bigger than necessary). + lwip_netconn_do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg + (see netconn_gethostbyname). */ +struct dns_api_msg { + /** Hostname to query or dotted IP address string */ + const char *name; + /** Rhe resolved address is stored here */ + ip_addr_t *addr; + /** This semaphore is posted when the name is resolved, the application thread + should wait on it. */ + sys_sem_t *sem; + /** Errors are given back here */ + err_t *err; +}; +#endif /* LWIP_DNS */ + +void lwip_netconn_do_newconn ( struct api_msg_msg *msg); +void lwip_netconn_do_delconn ( struct api_msg_msg *msg); +void lwip_netconn_do_bind ( struct api_msg_msg *msg); +void lwip_netconn_do_connect ( struct api_msg_msg *msg); +void lwip_netconn_do_disconnect ( struct api_msg_msg *msg); +void lwip_netconn_do_listen ( struct api_msg_msg *msg); +void lwip_netconn_do_send ( struct api_msg_msg *msg); +void lwip_netconn_do_recv ( struct api_msg_msg *msg); +void lwip_netconn_do_write ( struct api_msg_msg *msg); +void lwip_netconn_do_getaddr ( struct api_msg_msg *msg); +void lwip_netconn_do_close ( struct api_msg_msg *msg); +void lwip_netconn_do_shutdown ( struct api_msg_msg *msg); +#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) +void lwip_netconn_do_join_leave_group( struct api_msg_msg *msg); +#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + +#if LWIP_DNS +void lwip_netconn_do_gethostbyname(void *arg); +#endif /* LWIP_DNS */ + +struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback); +void netconn_free(struct netconn *conn); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN */ + +#endif /* __LWIP_API_MSG_H__ */ diff --git a/include/lwip/lwip/arch.h b/include/lwip/lwip/arch.h index 919a6cf7..4d6df773 100644 --- a/include/lwip/lwip/arch.h +++ b/include/lwip/lwip/arch.h @@ -1,217 +1,217 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_ARCH_H__ -#define __LWIP_ARCH_H__ - -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif - -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#endif - -#include "arch/cc.h" - -/** Temporary: define format string for size_t if not defined in cc.h */ -#ifndef SZT_F -#define SZT_F U32_F -#endif /* SZT_F */ -/** Temporary upgrade helper: define format string for u8_t as hex if not - defined in cc.h */ -#ifndef X8_F -#define X8_F "02x" -#endif /* X8_F */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef PACK_STRUCT_BEGIN -#define PACK_STRUCT_BEGIN -#endif /* PACK_STRUCT_BEGIN */ - -#ifndef PACK_STRUCT_END -#define PACK_STRUCT_END -#endif /* PACK_STRUCT_END */ - -#ifndef PACK_STRUCT_FIELD -#define PACK_STRUCT_FIELD(x) x -#endif /* PACK_STRUCT_FIELD */ - - -#ifndef LWIP_UNUSED_ARG -#define LWIP_UNUSED_ARG(x) (void)x -#endif /* LWIP_UNUSED_ARG */ - - -#ifdef LWIP_PROVIDE_ERRNO - -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* Out of memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math argument out of domain of func */ -#define ERANGE 34 /* Math result not representable */ -#define EDEADLK 35 /* Resource deadlock would occur */ -#define ENAMETOOLONG 36 /* File name too long */ -#define ENOLCK 37 /* No record locks available */ -#define ENOSYS 38 /* Function not implemented */ -#define ENOTEMPTY 39 /* Directory not empty */ -#define ELOOP 40 /* Too many symbolic links encountered */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define ENOMSG 42 /* No message of desired type */ -#define EIDRM 43 /* Identifier removed */ -#define ECHRNG 44 /* Channel number out of range */ -#define EL2NSYNC 45 /* Level 2 not synchronized */ -#define EL3HLT 46 /* Level 3 halted */ -#define EL3RST 47 /* Level 3 reset */ -#define ELNRNG 48 /* Link number out of range */ -#define EUNATCH 49 /* Protocol driver not attached */ -#define ENOCSI 50 /* No CSI structure available */ -#define EL2HLT 51 /* Level 2 halted */ -#define EBADE 52 /* Invalid exchange */ -#define EBADR 53 /* Invalid request descriptor */ -#define EXFULL 54 /* Exchange full */ -#define ENOANO 55 /* No anode */ -#define EBADRQC 56 /* Invalid request code */ -#define EBADSLT 57 /* Invalid slot */ - -#define EDEADLOCK EDEADLK - -#define EBFONT 59 /* Bad font file format */ -#define ENOSTR 60 /* Device not a stream */ -#define ENODATA 61 /* No data available */ -#define ETIME 62 /* Timer expired */ -#define ENOSR 63 /* Out of streams resources */ -#define ENONET 64 /* Machine is not on the network */ -#define ENOPKG 65 /* Package not installed */ -#define EREMOTE 66 /* Object is remote */ -#define ENOLINK 67 /* Link has been severed */ -#define EADV 68 /* Advertise error */ -#define ESRMNT 69 /* Srmount error */ -#define ECOMM 70 /* Communication error on send */ -#define EPROTO 71 /* Protocol error */ -#define EMULTIHOP 72 /* Multihop attempted */ -#define EDOTDOT 73 /* RFS specific error */ -#define EBADMSG 74 /* Not a data message */ -#define EOVERFLOW 75 /* Value too large for defined data type */ -#define ENOTUNIQ 76 /* Name not unique on network */ -#define EBADFD 77 /* File descriptor in bad state */ -#define EREMCHG 78 /* Remote address changed */ -#define ELIBACC 79 /* Can not access a needed shared library */ -#define ELIBBAD 80 /* Accessing a corrupted shared library */ -#define ELIBSCN 81 /* .lib section in a.out corrupted */ -#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ -#define ELIBEXEC 83 /* Cannot exec a shared library directly */ -#define EILSEQ 84 /* Illegal byte sequence */ -#define ERESTART 85 /* Interrupted system call should be restarted */ -#define ESTRPIPE 86 /* Streams pipe error */ -#define EUSERS 87 /* Too many users */ -#define ENOTSOCK 88 /* Socket operation on non-socket */ -#define EDESTADDRREQ 89 /* Destination address required */ -#define EMSGSIZE 90 /* Message too long */ -#define EPROTOTYPE 91 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 92 /* Protocol not available */ -#define EPROTONOSUPPORT 93 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ -#define EPFNOSUPPORT 96 /* Protocol family not supported */ -#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ -#define EADDRINUSE 98 /* Address already in use */ -#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ -#define ENETDOWN 100 /* Network is down */ -#define ENETUNREACH 101 /* Network is unreachable */ -#define ENETRESET 102 /* Network dropped connection because of reset */ -#define ECONNABORTED 103 /* Software caused connection abort */ -#define ECONNRESET 104 /* Connection reset by peer */ -#define ENOBUFS 105 /* No buffer space available */ -#define EISCONN 106 /* Transport endpoint is already connected */ -#define ENOTCONN 107 /* Transport endpoint is not connected */ -#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ -#define ETOOMANYREFS 109 /* Too many references: cannot splice */ -#define ETIMEDOUT 110 /* Connection timed out */ -#define ECONNREFUSED 111 /* Connection refused */ -#define EHOSTDOWN 112 /* Host is down */ -#define EHOSTUNREACH 113 /* No route to host */ -#define EALREADY 114 /* Operation already in progress */ -#define EINPROGRESS 115 /* Operation now in progress */ -#define ESTALE 116 /* Stale NFS file handle */ -#define EUCLEAN 117 /* Structure needs cleaning */ -#define ENOTNAM 118 /* Not a XENIX named type file */ -#define ENAVAIL 119 /* No XENIX semaphores available */ -#define EISNAM 120 /* Is a named type file */ -#define EREMOTEIO 121 /* Remote I/O error */ -#define EDQUOT 122 /* Quota exceeded */ - -#define ENOMEDIUM 123 /* No medium found */ -#define EMEDIUMTYPE 124 /* Wrong medium type */ - -#ifndef errno -extern int errno; -#endif - -#endif /* LWIP_PROVIDE_ERRNO */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_ARCH_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ARCH_H__ +#define __LWIP_ARCH_H__ + +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif + +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif + +#include "arch/cc.h" + +/** Temporary: define format string for size_t if not defined in cc.h */ +#ifndef SZT_F +#define SZT_F U32_F +#endif /* SZT_F */ +/** Temporary upgrade helper: define format string for u8_t as hex if not + defined in cc.h */ +#ifndef X8_F +#define X8_F "02x" +#endif /* X8_F */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PACK_STRUCT_BEGIN +#define PACK_STRUCT_BEGIN +#endif /* PACK_STRUCT_BEGIN */ + +#ifndef PACK_STRUCT_END +#define PACK_STRUCT_END +#endif /* PACK_STRUCT_END */ + +#ifndef PACK_STRUCT_FIELD +#define PACK_STRUCT_FIELD(x) x +#endif /* PACK_STRUCT_FIELD */ + + +#ifndef LWIP_UNUSED_ARG +#define LWIP_UNUSED_ARG(x) (void)x +#endif /* LWIP_UNUSED_ARG */ + + +#ifdef LWIP_PROVIDE_ERRNO + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#ifndef errno +extern int errno; +#endif + +#endif /* LWIP_PROVIDE_ERRNO */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ARCH_H__ */ diff --git a/include/lwip/lwip/debug.h b/include/lwip/lwip/debug.h index 7c4143a5..0fe04139 100644 --- a/include/lwip/lwip/debug.h +++ b/include/lwip/lwip/debug.h @@ -1,99 +1,99 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_DEBUG_H__ -#define __LWIP_DEBUG_H__ - -#include "lwip/arch.h" -#include "lwip/opt.h" - -/** lower two bits indicate debug level - * - 0 all - * - 1 warning - * - 2 serious - * - 3 severe - */ -#define LWIP_DBG_LEVEL_ALL 0x00 -#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL /* compatibility define only */ -#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */ -#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */ -#define LWIP_DBG_LEVEL_SEVERE 0x03 -#define LWIP_DBG_MASK_LEVEL 0x03 - -/** flag for LWIP_DEBUGF to enable that debug message */ -#define LWIP_DBG_ON 0x80U -/** flag for LWIP_DEBUGF to disable that debug message */ -#define LWIP_DBG_OFF 0x00U - -/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */ -#define LWIP_DBG_TRACE 0x40U -/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */ -#define LWIP_DBG_STATE 0x20U -/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */ -#define LWIP_DBG_FRESH 0x10U -/** flag for LWIP_DEBUGF to halt after printing this debug message */ -#define LWIP_DBG_HALT 0x08U - -#ifndef LWIP_NOASSERT -#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \ - LWIP_PLATFORM_ASSERT(message); } while(0) -#else /* LWIP_NOASSERT */ -#define LWIP_ASSERT(message, assertion) -#endif /* LWIP_NOASSERT */ - -/** if "expression" isn't true, then print "message" and execute "handler" expression */ -#ifndef LWIP_ERROR -#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ - LWIP_PLATFORM_ASSERT(message); handler;}} while(0) -#endif /* LWIP_ERROR */ - -#ifdef LWIP_DEBUG -/** print debug message only if debug message type is enabled... - * AND is of correct type AND is at least LWIP_DBG_LEVEL - */ -#define LWIP_DEBUGF(debug, message) do { \ - if ( \ - ((debug) & LWIP_DBG_ON) && \ - ((debug) & LWIP_DBG_TYPES_ON) && \ - ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ - LWIP_PLATFORM_DIAG(message); \ - if ((debug) & LWIP_DBG_HALT) { \ - while(1); \ - } \ - } \ - } while(0) - -#else /* LWIP_DEBUG */ -#define LWIP_DEBUGF(debug, message) -#endif /* LWIP_DEBUG */ - -#endif /* __LWIP_DEBUG_H__ */ - +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_DEBUG_H__ +#define __LWIP_DEBUG_H__ + +#include "lwip/arch.h" +#include "lwip/opt.h" + +/** lower two bits indicate debug level + * - 0 all + * - 1 warning + * - 2 serious + * - 3 severe + */ +#define LWIP_DBG_LEVEL_ALL 0x00 +#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL /* compatibility define only */ +#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */ +#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */ +#define LWIP_DBG_LEVEL_SEVERE 0x03 +#define LWIP_DBG_MASK_LEVEL 0x03 + +/** flag for LWIP_DEBUGF to enable that debug message */ +#define LWIP_DBG_ON 0x80U +/** flag for LWIP_DEBUGF to disable that debug message */ +#define LWIP_DBG_OFF 0x00U + +/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */ +#define LWIP_DBG_TRACE 0x40U +/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */ +#define LWIP_DBG_STATE 0x20U +/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */ +#define LWIP_DBG_FRESH 0x10U +/** flag for LWIP_DEBUGF to halt after printing this debug message */ +#define LWIP_DBG_HALT 0x08U + +#ifndef LWIP_NOASSERT +#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \ + LWIP_PLATFORM_ASSERT(message); } while(0) +#else /* LWIP_NOASSERT */ +#define LWIP_ASSERT(message, assertion) +#endif /* LWIP_NOASSERT */ + +/** if "expression" isn't true, then print "message" and execute "handler" expression */ +#ifndef LWIP_ERROR +#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ + LWIP_PLATFORM_ASSERT(message); handler;}} while(0) +#endif /* LWIP_ERROR */ + +#ifdef LWIP_DEBUG +/** print debug message only if debug message type is enabled... + * AND is of correct type AND is at least LWIP_DBG_LEVEL + */ +#define LWIP_DEBUGF(debug, message) do { \ + if ( \ + ((debug) & LWIP_DBG_ON) && \ + ((debug) & LWIP_DBG_TYPES_ON) && \ + ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ + LWIP_PLATFORM_DIAG(message); \ + if ((debug) & LWIP_DBG_HALT) { \ + while(1); \ + } \ + } \ + } while(0) + +#else /* LWIP_DEBUG */ +#define LWIP_DEBUGF(debug, message) +#endif /* LWIP_DEBUG */ + +#endif /* __LWIP_DEBUG_H__ */ + diff --git a/include/lwip/lwip/def.h b/include/lwip/lwip/def.h index 0349cfe7..9b6de6a8 100644 --- a/include/lwip/lwip/def.h +++ b/include/lwip/lwip/def.h @@ -1,127 +1,127 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_DEF_H__ -#define __LWIP_DEF_H__ - -/* arch.h might define NULL already */ -#include "lwip/arch.h" -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y)) -#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y)) - -#ifndef NULL -#define NULL ((void *)0) -#endif - -/** Get the absolute difference between 2 u32_t values (correcting overflows) - * 'a' is expected to be 'higher' (without overflow) than 'b'. */ -#define LWIP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : (((a) + ((b) ^ 0xFFFFFFFF) + 1))) - -/* Endianess-optimized shifting of two u8_t to create one u16_t */ -#if BYTE_ORDER == LITTLE_ENDIAN -#define LWIP_MAKE_U16(a, b) ((a << 8) | b) -#else -#define LWIP_MAKE_U16(a, b) ((b << 8) | a) -#endif - -#ifndef LWIP_PLATFORM_BYTESWAP -#define LWIP_PLATFORM_BYTESWAP 0 -#endif - -#ifndef LWIP_PREFIX_BYTEORDER_FUNCS -/* workaround for naming collisions on some platforms */ - -#ifdef htons -#undef htons -#endif /* htons */ -#ifdef htonl -#undef htonl -#endif /* htonl */ -#ifdef ntohs -#undef ntohs -#endif /* ntohs */ -#ifdef ntohl -#undef ntohl -#endif /* ntohl */ - -#define htons(x) lwip_htons(x) -#define ntohs(x) lwip_ntohs(x) -#define htonl(x) lwip_htonl(x) -#define ntohl(x) lwip_ntohl(x) -#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */ - -#if BYTE_ORDER == BIG_ENDIAN -#define lwip_htons(x) (x) -#define lwip_ntohs(x) (x) -#define lwip_htonl(x) (x) -#define lwip_ntohl(x) (x) -#define PP_HTONS(x) (x) -#define PP_NTOHS(x) (x) -#define PP_HTONL(x) (x) -#define PP_NTOHL(x) (x) -#else /* BYTE_ORDER != BIG_ENDIAN */ -#if LWIP_PLATFORM_BYTESWAP -#define lwip_htons(x) LWIP_PLATFORM_HTONS(x) -#define lwip_ntohs(x) LWIP_PLATFORM_HTONS(x) -#define lwip_htonl(x) LWIP_PLATFORM_HTONL(x) -#define lwip_ntohl(x) LWIP_PLATFORM_HTONL(x) -#else /* LWIP_PLATFORM_BYTESWAP */ -u16_t lwip_htons(u16_t x); -u16_t lwip_ntohs(u16_t x); -u32_t lwip_htonl(u32_t x); -u32_t lwip_ntohl(u32_t x); -#endif /* LWIP_PLATFORM_BYTESWAP */ - -/* These macros should be calculated by the preprocessor and are used - with compile-time constants only (so that there is no little-endian - overhead at runtime). */ -#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) -#define PP_NTOHS(x) PP_HTONS(x) -#define PP_HTONL(x) ((((x) & 0xff) << 24) | \ - (((x) & 0xff00) << 8) | \ - (((x) & 0xff0000UL) >> 8) | \ - (((x) & 0xff000000UL) >> 24)) -#define PP_NTOHL(x) PP_HTONL(x) - -#endif /* BYTE_ORDER == BIG_ENDIAN */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_DEF_H__ */ - +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_DEF_H__ +#define __LWIP_DEF_H__ + +/* arch.h might define NULL already */ +#include "lwip/arch.h" +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y)) +#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y)) + +#ifndef NULL +#define NULL ((void *)0) +#endif + +/** Get the absolute difference between 2 u32_t values (correcting overflows) + * 'a' is expected to be 'higher' (without overflow) than 'b'. */ +#define LWIP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : (((a) + ((b) ^ 0xFFFFFFFF) + 1))) + +/* Endianess-optimized shifting of two u8_t to create one u16_t */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define LWIP_MAKE_U16(a, b) ((a << 8) | b) +#else +#define LWIP_MAKE_U16(a, b) ((b << 8) | a) +#endif + +#ifndef LWIP_PLATFORM_BYTESWAP +#define LWIP_PLATFORM_BYTESWAP 0 +#endif + +#ifndef LWIP_PREFIX_BYTEORDER_FUNCS +/* workaround for naming collisions on some platforms */ + +#ifdef htons +#undef htons +#endif /* htons */ +#ifdef htonl +#undef htonl +#endif /* htonl */ +#ifdef ntohs +#undef ntohs +#endif /* ntohs */ +#ifdef ntohl +#undef ntohl +#endif /* ntohl */ + +#define htons(x) lwip_htons(x) +#define ntohs(x) lwip_ntohs(x) +#define htonl(x) lwip_htonl(x) +#define ntohl(x) lwip_ntohl(x) +#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */ + +#if BYTE_ORDER == BIG_ENDIAN +#define lwip_htons(x) (x) +#define lwip_ntohs(x) (x) +#define lwip_htonl(x) (x) +#define lwip_ntohl(x) (x) +#define PP_HTONS(x) (x) +#define PP_NTOHS(x) (x) +#define PP_HTONL(x) (x) +#define PP_NTOHL(x) (x) +#else /* BYTE_ORDER != BIG_ENDIAN */ +#if LWIP_PLATFORM_BYTESWAP +#define lwip_htons(x) LWIP_PLATFORM_HTONS(x) +#define lwip_ntohs(x) LWIP_PLATFORM_HTONS(x) +#define lwip_htonl(x) LWIP_PLATFORM_HTONL(x) +#define lwip_ntohl(x) LWIP_PLATFORM_HTONL(x) +#else /* LWIP_PLATFORM_BYTESWAP */ +u16_t lwip_htons(u16_t x); +u16_t lwip_ntohs(u16_t x); +u32_t lwip_htonl(u32_t x); +u32_t lwip_ntohl(u32_t x); +#endif /* LWIP_PLATFORM_BYTESWAP */ + +/* These macros should be calculated by the preprocessor and are used + with compile-time constants only (so that there is no little-endian + overhead at runtime). */ +#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) +#define PP_NTOHS(x) PP_HTONS(x) +#define PP_HTONL(x) ((((x) & 0xff) << 24) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000UL) >> 8) | \ + (((x) & 0xff000000UL) >> 24)) +#define PP_NTOHL(x) PP_HTONL(x) + +#endif /* BYTE_ORDER == BIG_ENDIAN */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_DEF_H__ */ + diff --git a/include/lwip/lwip/dhcp.h b/include/lwip/lwip/dhcp.h index c8f95aab..32b5028f 100644 --- a/include/lwip/lwip/dhcp.h +++ b/include/lwip/lwip/dhcp.h @@ -1,254 +1,254 @@ -/** @file - */ - -#ifndef __LWIP_DHCP_H__ -#define __LWIP_DHCP_H__ - -#include "lwip/opt.h" - -#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netif.h" -#include "lwip/udp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** period (in seconds) of the application calling dhcp_coarse_tmr() */ -#define DHCP_COARSE_TIMER_SECS 60 -/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ -#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL) -/** period (in milliseconds) of the application calling dhcp_fine_tmr() */ -#define DHCP_FINE_TIMER_MSECS 500 - -#define DHCP_CHADDR_LEN 16U -#define DHCP_SNAME_LEN 64U -#define DHCP_FILE_LEN 128U - -struct dhcp -{ - /** transaction identifier of last sent request */ - u32_t xid; - /** our connection to the DHCP server */ - struct udp_pcb *pcb; - /** incoming msg */ - struct dhcp_msg *msg_in; - /** current DHCP state machine state */ - u8_t state; - /** retries of current request */ - u8_t tries; -#if LWIP_DHCP_AUTOIP_COOP - u8_t autoip_coop_state; -#endif - u8_t subnet_mask_given; - - struct pbuf *p_out; /* pbuf of outcoming msg */ - struct dhcp_msg *msg_out; /* outgoing msg */ - u16_t options_out_len; /* outgoing msg options length */ - u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ - u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ - u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ - ip_addr_t server_ip_addr; /* dhcp server address that offered this lease */ - ip_addr_t offered_ip_addr; - ip_addr_t offered_sn_mask; - ip_addr_t offered_gw_addr; - - u32_t offered_t0_lease; /* lease period (in seconds) */ - u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ - u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period) */ - /* @todo: LWIP_DHCP_BOOTP_FILE configuration option? - integrate with possible TFTP-client for booting? */ -#if LWIP_DHCP_BOOTP_FILE - ip_addr_t offered_si_addr; - char boot_file_name[DHCP_FILE_LEN]; -#endif /* LWIP_DHCP_BOOTPFILE */ -}; - -/* MUST be compiled with "pack structs" or equivalent! */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** minimum set of fields of any DHCP message */ -struct dhcp_msg -{ - PACK_STRUCT_FIELD(u8_t op); - PACK_STRUCT_FIELD(u8_t htype); - PACK_STRUCT_FIELD(u8_t hlen); - PACK_STRUCT_FIELD(u8_t hops); - PACK_STRUCT_FIELD(u32_t xid); - PACK_STRUCT_FIELD(u16_t secs); - PACK_STRUCT_FIELD(u16_t flags); - PACK_STRUCT_FIELD(ip_addr_p_t ciaddr); - PACK_STRUCT_FIELD(ip_addr_p_t yiaddr); - PACK_STRUCT_FIELD(ip_addr_p_t siaddr); - PACK_STRUCT_FIELD(ip_addr_p_t giaddr); - PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]); - PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]); - PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]); - PACK_STRUCT_FIELD(u32_t cookie); -#define DHCP_MIN_OPTIONS_LEN 68U -/** make sure user does not configure this too small */ -#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN)) -# undef DHCP_OPTIONS_LEN -#endif -/** allow this to be configured in lwipopts.h, but not too small */ -#if (!defined(DHCP_OPTIONS_LEN)) -/** set this to be sufficient for your options in outgoing DHCP msgs */ -# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN -#endif - PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp); -/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */ -#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0) -void dhcp_cleanup(struct netif *netif); -/** start DHCP configuration */ -err_t dhcp_start(struct netif *netif); -/** enforce early lease renewal (not needed normally)*/ -err_t dhcp_renew(struct netif *netif); -/** release the DHCP lease, usually called before dhcp_stop()*/ -err_t dhcp_release(struct netif *netif); -/** stop DHCP configuration */ -void dhcp_stop(struct netif *netif); -/** inform server of our manual IP address */ -void dhcp_inform(struct netif *netif); -/** Handle a possible change in the network configuration */ -void dhcp_network_changed(struct netif *netif); - -/** if enabled, check whether the offered IP address is not in use, using ARP */ -#if DHCP_DOES_ARP_CHECK -void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr); -#endif - -/** to be called every minute */ -void dhcp_coarse_tmr(void); -/** to be called every half second */ -void dhcp_fine_tmr(void); - -/** DHCP message item offsets and length */ -#define DHCP_OP_OFS 0 -#define DHCP_HTYPE_OFS 1 -#define DHCP_HLEN_OFS 2 -#define DHCP_HOPS_OFS 3 -#define DHCP_XID_OFS 4 -#define DHCP_SECS_OFS 8 -#define DHCP_FLAGS_OFS 10 -#define DHCP_CIADDR_OFS 12 -#define DHCP_YIADDR_OFS 16 -#define DHCP_SIADDR_OFS 20 -#define DHCP_GIADDR_OFS 24 -#define DHCP_CHADDR_OFS 28 -#define DHCP_SNAME_OFS 44 -#define DHCP_FILE_OFS 108 -#define DHCP_MSG_LEN 236 - -#define DHCP_COOKIE_OFS DHCP_MSG_LEN -#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4) - -#define DHCP_CLIENT_PORT 68 -#define DHCP_SERVER_PORT 67 - -/** DHCP client states */ -#define DHCP_OFF 0 -#define DHCP_REQUESTING 1 -#define DHCP_INIT 2 -#define DHCP_REBOOTING 3 -#define DHCP_REBINDING 4 -#define DHCP_RENEWING 5 -#define DHCP_SELECTING 6 -#define DHCP_INFORMING 7 -#define DHCP_CHECKING 8 -#define DHCP_PERMANENT 9 -#define DHCP_BOUND 10 -/** not yet implemented #define DHCP_RELEASING 11 */ -#define DHCP_BACKING_OFF 12 - -/** AUTOIP cooperatation flags */ -#define DHCP_AUTOIP_COOP_STATE_OFF 0 -#define DHCP_AUTOIP_COOP_STATE_ON 1 - -#define DHCP_BOOTREQUEST 1 -#define DHCP_BOOTREPLY 2 - -/** DHCP message types */ -#define DHCP_DISCOVER 1 -#define DHCP_OFFER 2 -#define DHCP_REQUEST 3 -#define DHCP_DECLINE 4 -#define DHCP_ACK 5 -#define DHCP_NAK 6 -#define DHCP_RELEASE 7 -#define DHCP_INFORM 8 - -/** DHCP hardware type, currently only ethernet is supported */ -#define DHCP_HTYPE_ETH 1 - -#define DHCP_MAGIC_COOKIE 0x63825363UL - -/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */ - -/** BootP options */ -#define DHCP_OPTION_PAD 0 -#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */ -#define DHCP_OPTION_ROUTER 3 -#define DHCP_OPTION_DNS_SERVER 6 -#define DHCP_OPTION_HOSTNAME 12 -#define DHCP_OPTION_IP_TTL 23 -#define DHCP_OPTION_MTU 26 -#define DHCP_OPTION_BROADCAST 28 -#define DHCP_OPTION_TCP_TTL 37 -#define DHCP_OPTION_END 255 - -/**add options for support more router by liuHan**/ -#ifdef LWIP_ESP8266 -#define DHCP_OPTION_DOMAIN_NAME 15 -#define DHCP_OPTION_PRD 31 -#define DHCP_OPTION_STATIC_ROUTER 33 -#define DHCP_OPTION_VSN 43 -#define DHCP_OPTION_NB_TINS 44 -#define DHCP_OPTION_NB_TINT 46 -#define DHCP_OPTION_NB_TIS 47 -#define DHCP_OPTION_CLASSLESS_STATIC_ROUTER 121 - -#endif -/** DHCP options */ -#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */ -#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */ -#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */ - -#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ -#define DHCP_OPTION_MESSAGE_TYPE_LEN 1 - -#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */ -#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */ - -#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */ -#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2 - -#define DHCP_OPTION_T1 58 /* T1 renewal time */ -#define DHCP_OPTION_T2 59 /* T2 rebinding time */ -#define DHCP_OPTION_US 60 -#define DHCP_OPTION_CLIENT_ID 61 -#define DHCP_OPTION_TFTP_SERVERNAME 66 -#define DHCP_OPTION_BOOTFILE 67 - -/** possible combinations of overloading the file and sname fields with options */ -#define DHCP_OVERLOAD_NONE 0 -#define DHCP_OVERLOAD_FILE 1 -#define DHCP_OVERLOAD_SNAME 2 -#define DHCP_OVERLOAD_SNAME_FILE 3 - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DHCP */ - -#endif /*__LWIP_DHCP_H__*/ +/** @file + */ + +#ifndef __LWIP_DHCP_H__ +#define __LWIP_DHCP_H__ + +#include "lwip/opt.h" + +#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** period (in seconds) of the application calling dhcp_coarse_tmr() */ +#define DHCP_COARSE_TIMER_SECS 60 +/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ +#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL) +/** period (in milliseconds) of the application calling dhcp_fine_tmr() */ +#define DHCP_FINE_TIMER_MSECS 500 + +#define DHCP_CHADDR_LEN 16U +#define DHCP_SNAME_LEN 64U +#define DHCP_FILE_LEN 128U + +struct dhcp +{ + /** transaction identifier of last sent request */ + u32_t xid; + /** our connection to the DHCP server */ + struct udp_pcb *pcb; + /** incoming msg */ + struct dhcp_msg *msg_in; + /** current DHCP state machine state */ + u8_t state; + /** retries of current request */ + u8_t tries; +#if LWIP_DHCP_AUTOIP_COOP + u8_t autoip_coop_state; +#endif + u8_t subnet_mask_given; + + struct pbuf *p_out; /* pbuf of outcoming msg */ + struct dhcp_msg *msg_out; /* outgoing msg */ + u16_t options_out_len; /* outgoing msg options length */ + u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ + u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ + u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ + ip_addr_t server_ip_addr; /* dhcp server address that offered this lease */ + ip_addr_t offered_ip_addr; + ip_addr_t offered_sn_mask; + ip_addr_t offered_gw_addr; + + u32_t offered_t0_lease; /* lease period (in seconds) */ + u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ + u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period) */ + /* @todo: LWIP_DHCP_BOOTP_FILE configuration option? + integrate with possible TFTP-client for booting? */ +#if LWIP_DHCP_BOOTP_FILE + ip_addr_t offered_si_addr; + char boot_file_name[DHCP_FILE_LEN]; +#endif /* LWIP_DHCP_BOOTPFILE */ +}; + +/* MUST be compiled with "pack structs" or equivalent! */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** minimum set of fields of any DHCP message */ +struct dhcp_msg +{ + PACK_STRUCT_FIELD(u8_t op); + PACK_STRUCT_FIELD(u8_t htype); + PACK_STRUCT_FIELD(u8_t hlen); + PACK_STRUCT_FIELD(u8_t hops); + PACK_STRUCT_FIELD(u32_t xid); + PACK_STRUCT_FIELD(u16_t secs); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FIELD(ip_addr_p_t ciaddr); + PACK_STRUCT_FIELD(ip_addr_p_t yiaddr); + PACK_STRUCT_FIELD(ip_addr_p_t siaddr); + PACK_STRUCT_FIELD(ip_addr_p_t giaddr); + PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]); + PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]); + PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]); + PACK_STRUCT_FIELD(u32_t cookie); +#define DHCP_MIN_OPTIONS_LEN 68U +/** make sure user does not configure this too small */ +#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN)) +# undef DHCP_OPTIONS_LEN +#endif +/** allow this to be configured in lwipopts.h, but not too small */ +#if (!defined(DHCP_OPTIONS_LEN)) +/** set this to be sufficient for your options in outgoing DHCP msgs */ +# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN +#endif + PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp); +/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */ +#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0) +void dhcp_cleanup(struct netif *netif); +/** start DHCP configuration */ +err_t dhcp_start(struct netif *netif); +/** enforce early lease renewal (not needed normally)*/ +err_t dhcp_renew(struct netif *netif); +/** release the DHCP lease, usually called before dhcp_stop()*/ +err_t dhcp_release(struct netif *netif); +/** stop DHCP configuration */ +void dhcp_stop(struct netif *netif); +/** inform server of our manual IP address */ +void dhcp_inform(struct netif *netif); +/** Handle a possible change in the network configuration */ +void dhcp_network_changed(struct netif *netif); + +/** if enabled, check whether the offered IP address is not in use, using ARP */ +#if DHCP_DOES_ARP_CHECK +void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr); +#endif + +/** to be called every minute */ +void dhcp_coarse_tmr(void); +/** to be called every half second */ +void dhcp_fine_tmr(void); + +/** DHCP message item offsets and length */ +#define DHCP_OP_OFS 0 +#define DHCP_HTYPE_OFS 1 +#define DHCP_HLEN_OFS 2 +#define DHCP_HOPS_OFS 3 +#define DHCP_XID_OFS 4 +#define DHCP_SECS_OFS 8 +#define DHCP_FLAGS_OFS 10 +#define DHCP_CIADDR_OFS 12 +#define DHCP_YIADDR_OFS 16 +#define DHCP_SIADDR_OFS 20 +#define DHCP_GIADDR_OFS 24 +#define DHCP_CHADDR_OFS 28 +#define DHCP_SNAME_OFS 44 +#define DHCP_FILE_OFS 108 +#define DHCP_MSG_LEN 236 + +#define DHCP_COOKIE_OFS DHCP_MSG_LEN +#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4) + +#define DHCP_CLIENT_PORT 68 +#define DHCP_SERVER_PORT 67 + +/** DHCP client states */ +#define DHCP_OFF 0 +#define DHCP_REQUESTING 1 +#define DHCP_INIT 2 +#define DHCP_REBOOTING 3 +#define DHCP_REBINDING 4 +#define DHCP_RENEWING 5 +#define DHCP_SELECTING 6 +#define DHCP_INFORMING 7 +#define DHCP_CHECKING 8 +#define DHCP_PERMANENT 9 +#define DHCP_BOUND 10 +/** not yet implemented #define DHCP_RELEASING 11 */ +#define DHCP_BACKING_OFF 12 + +/** AUTOIP cooperatation flags */ +#define DHCP_AUTOIP_COOP_STATE_OFF 0 +#define DHCP_AUTOIP_COOP_STATE_ON 1 + +#define DHCP_BOOTREQUEST 1 +#define DHCP_BOOTREPLY 2 + +/** DHCP message types */ +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 + +/** DHCP hardware type, currently only ethernet is supported */ +#define DHCP_HTYPE_ETH 1 + +#define DHCP_MAGIC_COOKIE 0x63825363UL + +/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */ + +/** BootP options */ +#define DHCP_OPTION_PAD 0 +#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */ +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_HOSTNAME 12 +#define DHCP_OPTION_IP_TTL 23 +#define DHCP_OPTION_MTU 26 +#define DHCP_OPTION_BROADCAST 28 +#define DHCP_OPTION_TCP_TTL 37 +#define DHCP_OPTION_END 255 + +/**add options for support more router by liuHan**/ +#ifdef LWIP_ESP8266 +#define DHCP_OPTION_DOMAIN_NAME 15 +#define DHCP_OPTION_PRD 31 +#define DHCP_OPTION_STATIC_ROUTER 33 +#define DHCP_OPTION_VSN 43 +#define DHCP_OPTION_NB_TINS 44 +#define DHCP_OPTION_NB_TINT 46 +#define DHCP_OPTION_NB_TIS 47 +#define DHCP_OPTION_CLASSLESS_STATIC_ROUTER 121 + +#endif +/** DHCP options */ +#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */ +#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */ +#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */ + +#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ +#define DHCP_OPTION_MESSAGE_TYPE_LEN 1 + +#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */ +#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */ + +#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */ +#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2 + +#define DHCP_OPTION_T1 58 /* T1 renewal time */ +#define DHCP_OPTION_T2 59 /* T2 rebinding time */ +#define DHCP_OPTION_US 60 +#define DHCP_OPTION_CLIENT_ID 61 +#define DHCP_OPTION_TFTP_SERVERNAME 66 +#define DHCP_OPTION_BOOTFILE 67 + +/** possible combinations of overloading the file and sname fields with options */ +#define DHCP_OVERLOAD_NONE 0 +#define DHCP_OVERLOAD_FILE 1 +#define DHCP_OVERLOAD_SNAME 2 +#define DHCP_OVERLOAD_SNAME_FILE 3 + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DHCP */ + +#endif /*__LWIP_DHCP_H__*/ diff --git a/include/lwip/lwip/dhcpserver.h b/include/lwip/lwip/dhcpserver.h index f959abb4..1e45a09b 100644 --- a/include/lwip/lwip/dhcpserver.h +++ b/include/lwip/lwip/dhcpserver.h @@ -1,102 +1,102 @@ -#ifndef __DHCPS_H__ -#define __DHCPS_H__ - -#define USE_DNS - -typedef struct dhcps_state{ - s16_t state; -} dhcps_state; - -// ����dhcpclient�Զ����һ��DHCP msg�ṹ�� -typedef struct dhcps_msg { - u8_t op, htype, hlen, hops; - u8_t xid[4]; - u16_t secs, flags; - u8_t ciaddr[4]; - u8_t yiaddr[4]; - u8_t siaddr[4]; - u8_t giaddr[4]; - u8_t chaddr[16]; - u8_t sname[64]; - u8_t file[128]; - u8_t options[312]; -}dhcps_msg; - -#ifndef LWIP_OPEN_SRC -struct dhcps_lease { - bool enable; - struct ip_addr start_ip; - struct ip_addr end_ip; -}; - -enum dhcps_offer_option{ - OFFER_START = 0x00, - OFFER_ROUTER = 0x01, - OFFER_END -}; -#endif - -struct dhcps_pool{ - struct ip_addr ip; - u8_t mac[6]; - u32_t lease_timer; -}; - -typedef struct _list_node{ - void *pnode; - struct _list_node *pnext; -}list_node; - -extern u32_t dhcps_lease_time; -#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0 -#define DHCPS_MAX_LEASE 0x64 -#define BOOTP_BROADCAST 0x8000 - -#define DHCP_REQUEST 1 -#define DHCP_REPLY 2 -#define DHCP_HTYPE_ETHERNET 1 -#define DHCP_HLEN_ETHERNET 6 -#define DHCP_MSG_LEN 236 - -#define DHCPS_SERVER_PORT 67 -#define DHCPS_CLIENT_PORT 68 - -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPDECLINE 4 -#define DHCPACK 5 -#define DHCPNAK 6 -#define DHCPRELEASE 7 - -#define DHCP_OPTION_SUBNET_MASK 1 -#define DHCP_OPTION_ROUTER 3 -#define DHCP_OPTION_DNS_SERVER 6 -#define DHCP_OPTION_REQ_IPADDR 50 -#define DHCP_OPTION_LEASE_TIME 51 -#define DHCP_OPTION_MSG_TYPE 53 -#define DHCP_OPTION_SERVER_ID 54 -#define DHCP_OPTION_INTERFACE_MTU 26 -#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31 -#define DHCP_OPTION_BROADCAST_ADDRESS 28 -#define DHCP_OPTION_REQ_LIST 55 -#define DHCP_OPTION_END 255 - -//#define USE_CLASS_B_NET 1 -#define DHCPS_DEBUG 0 -#define MAX_STATION_NUM 8 - -#define DHCPS_STATE_OFFER 1 -#define DHCPS_STATE_DECLINE 2 -#define DHCPS_STATE_ACK 3 -#define DHCPS_STATE_NAK 4 -#define DHCPS_STATE_IDLE 5 -#define DHCPS_STATE_RELEASE 6 - -#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0) - -void dhcps_start(struct ip_info *info); -void dhcps_stop(void); - -#endif - +#ifndef __DHCPS_H__ +#define __DHCPS_H__ + +#define USE_DNS + +typedef struct dhcps_state{ + s16_t state; +} dhcps_state; + +// ����dhcpclient�Զ����һ��DHCP msg�ṹ�� +typedef struct dhcps_msg { + u8_t op, htype, hlen, hops; + u8_t xid[4]; + u16_t secs, flags; + u8_t ciaddr[4]; + u8_t yiaddr[4]; + u8_t siaddr[4]; + u8_t giaddr[4]; + u8_t chaddr[16]; + u8_t sname[64]; + u8_t file[128]; + u8_t options[312]; +}dhcps_msg; + +#ifndef LWIP_OPEN_SRC +struct dhcps_lease { + bool enable; + struct ip_addr start_ip; + struct ip_addr end_ip; +}; + +enum dhcps_offer_option{ + OFFER_START = 0x00, + OFFER_ROUTER = 0x01, + OFFER_END +}; +#endif + +struct dhcps_pool{ + struct ip_addr ip; + u8_t mac[6]; + u32_t lease_timer; +}; + +typedef struct _list_node{ + void *pnode; + struct _list_node *pnext; +}list_node; + +extern u32_t dhcps_lease_time; +#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0 +#define DHCPS_MAX_LEASE 0x64 +#define BOOTP_BROADCAST 0x8000 + +#define DHCP_REQUEST 1 +#define DHCP_REPLY 2 +#define DHCP_HTYPE_ETHERNET 1 +#define DHCP_HLEN_ETHERNET 6 +#define DHCP_MSG_LEN 236 + +#define DHCPS_SERVER_PORT 67 +#define DHCPS_CLIENT_PORT 68 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_SUBNET_MASK 1 +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_REQ_IPADDR 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_MSG_TYPE 53 +#define DHCP_OPTION_SERVER_ID 54 +#define DHCP_OPTION_INTERFACE_MTU 26 +#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31 +#define DHCP_OPTION_BROADCAST_ADDRESS 28 +#define DHCP_OPTION_REQ_LIST 55 +#define DHCP_OPTION_END 255 + +//#define USE_CLASS_B_NET 1 +#define DHCPS_DEBUG 0 +#define MAX_STATION_NUM 8 + +#define DHCPS_STATE_OFFER 1 +#define DHCPS_STATE_DECLINE 2 +#define DHCPS_STATE_ACK 3 +#define DHCPS_STATE_NAK 4 +#define DHCPS_STATE_IDLE 5 +#define DHCPS_STATE_RELEASE 6 + +#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0) + +void dhcps_start(struct ip_info *info); +void dhcps_stop(void); + +#endif + diff --git a/include/lwip/lwip/dns.h b/include/lwip/lwip/dns.h index dacc6be8..11a5747f 100644 --- a/include/lwip/lwip/dns.h +++ b/include/lwip/lwip/dns.h @@ -1,125 +1,125 @@ -/** - * lwip DNS resolver header file. - - * Author: Jim Pettinato - * April 2007 - - * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __LWIP_DNS_H__ -#define __LWIP_DNS_H__ - -#include "lwip/opt.h" -#include "lwip/err.h" - -#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** DNS timer period */ -#define DNS_TMR_INTERVAL 1000 - -/** DNS field TYPE used for "Resource Records" */ -#define DNS_RRTYPE_A 1 /* a host address */ -#define DNS_RRTYPE_NS 2 /* an authoritative name server */ -#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */ -#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */ -#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */ -#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */ -#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */ -#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */ -#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */ -#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */ -#define DNS_RRTYPE_WKS 11 /* a well known service description */ -#define DNS_RRTYPE_PTR 12 /* a domain name pointer */ -#define DNS_RRTYPE_HINFO 13 /* host information */ -#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ -#define DNS_RRTYPE_MX 15 /* mail exchange */ -#define DNS_RRTYPE_TXT 16 /* text strings */ - -/** DNS field CLASS used for "Resource Records" */ -#define DNS_RRCLASS_IN 1 /* the Internet */ -#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */ -#define DNS_RRCLASS_CH 3 /* the CHAOS class */ -#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ -#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ - -/* The size used for the next line is rather a hack, but it prevents including socket.h in all files - that include memp.h, and that would possibly break portability (since socket.h defines some types - and constants possibly already define by the OS). - Calculation rule: - sizeof(struct addrinfo) + sizeof(struct sockaddr_in) + DNS_MAX_NAME_LENGTH + 1 byte zero-termination */ -#define NETDB_ELEM_SIZE (32 + 16 + DNS_MAX_NAME_LENGTH + 1) - -#if DNS_LOCAL_HOSTLIST -/** struct used for local host-list */ -struct local_hostlist_entry { - /** static hostname */ - const char *name; - /** static host address in network byteorder */ - ip_addr_t addr; - struct local_hostlist_entry *next; -}; -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN -#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN DNS_MAX_NAME_LENGTH -#endif -#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1)) -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ -#endif /* DNS_LOCAL_HOSTLIST */ - -/** Callback which is invoked when a hostname is found. - * A function of this type must be implemented by the application using the DNS resolver. - * @param name pointer to the name that was looked up. - * @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname, - * or NULL if the name could not be found (or on any other error). - * @param callback_arg a user-specified callback argument passed to dns_gethostbyname -*/ -typedef void (*dns_found_callback)(const char *name, ip_addr_t *ipaddr, void *callback_arg); - -void dns_init(void); -void dns_tmr(void); -void dns_setserver(u8_t numdns, ip_addr_t *dnsserver); -ip_addr_t dns_getserver(u8_t numdns); -err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, - dns_found_callback found, void *callback_arg); - -#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC -int dns_local_removehost(const char *hostname, const ip_addr_t *addr); -err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr); -#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DNS */ - -#endif /* __LWIP_DNS_H__ */ +/** + * lwip DNS resolver header file. + + * Author: Jim Pettinato + * April 2007 + + * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LWIP_DNS_H__ +#define __LWIP_DNS_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" + +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** DNS timer period */ +#define DNS_TMR_INTERVAL 1000 + +/** DNS field TYPE used for "Resource Records" */ +#define DNS_RRTYPE_A 1 /* a host address */ +#define DNS_RRTYPE_NS 2 /* an authoritative name server */ +#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */ +#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */ +#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */ +#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */ +#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */ +#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */ +#define DNS_RRTYPE_WKS 11 /* a well known service description */ +#define DNS_RRTYPE_PTR 12 /* a domain name pointer */ +#define DNS_RRTYPE_HINFO 13 /* host information */ +#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ +#define DNS_RRTYPE_MX 15 /* mail exchange */ +#define DNS_RRTYPE_TXT 16 /* text strings */ + +/** DNS field CLASS used for "Resource Records" */ +#define DNS_RRCLASS_IN 1 /* the Internet */ +#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */ +#define DNS_RRCLASS_CH 3 /* the CHAOS class */ +#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ +#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ + +/* The size used for the next line is rather a hack, but it prevents including socket.h in all files + that include memp.h, and that would possibly break portability (since socket.h defines some types + and constants possibly already define by the OS). + Calculation rule: + sizeof(struct addrinfo) + sizeof(struct sockaddr_in) + DNS_MAX_NAME_LENGTH + 1 byte zero-termination */ +#define NETDB_ELEM_SIZE (32 + 16 + DNS_MAX_NAME_LENGTH + 1) + +#if DNS_LOCAL_HOSTLIST +/** struct used for local host-list */ +struct local_hostlist_entry { + /** static hostname */ + const char *name; + /** static host address in network byteorder */ + ip_addr_t addr; + struct local_hostlist_entry *next; +}; +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN +#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN DNS_MAX_NAME_LENGTH +#endif +#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1)) +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ +#endif /* DNS_LOCAL_HOSTLIST */ + +/** Callback which is invoked when a hostname is found. + * A function of this type must be implemented by the application using the DNS resolver. + * @param name pointer to the name that was looked up. + * @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname, + * or NULL if the name could not be found (or on any other error). + * @param callback_arg a user-specified callback argument passed to dns_gethostbyname +*/ +typedef void (*dns_found_callback)(const char *name, ip_addr_t *ipaddr, void *callback_arg); + +void dns_init(void); +void dns_tmr(void); +void dns_setserver(u8_t numdns, ip_addr_t *dnsserver); +ip_addr_t dns_getserver(u8_t numdns); +err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, + dns_found_callback found, void *callback_arg); + +#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC +int dns_local_removehost(const char *hostname, const ip_addr_t *addr); +err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr); +#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DNS */ + +#endif /* __LWIP_DNS_H__ */ diff --git a/include/lwip/lwip/err.h b/include/lwip/lwip/err.h index c1566b24..4501200a 100644 --- a/include/lwip/lwip/err.h +++ b/include/lwip/lwip/err.h @@ -1,101 +1,101 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_ERR_H__ -#define __LWIP_ERR_H__ - -#include "lwip/opt.h" -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Define LWIP_ERR_T in cc.h if you want to use - * a different type for your platform (must be signed). */ -#ifdef LWIP_ERR_T -typedef LWIP_ERR_T err_t; -#else /* LWIP_ERR_T */ -typedef s8_t err_t; -#endif /* LWIP_ERR_T*/ - -/* Definitions for error constants. */ - -#define ERR_OK 0 /* No error, everything OK. */ -#define ERR_MEM -1 /* Out of memory error. */ -#define ERR_BUF -2 /* Buffer error. */ -#define ERR_TIMEOUT -3 /* Timeout. */ -#define ERR_RTE -4 /* Routing problem. */ -#define ERR_INPROGRESS -5 /* Operation in progress */ -#define ERR_VAL -6 /* Illegal value. */ -#define ERR_WOULDBLOCK -7 /* Operation would block. */ -#define ERR_USE -8 /* Address in use. */ - -#ifdef LWIP_ESP8266 -#define ERR_ALREADY -9 /* Already connected. */ -#define ERR_ISCONN -10 /* Conn already established.*/ - -#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) - -#define ERR_ABRT -11 /* Connection aborted. */ -#define ERR_RST -12 /* Connection reset. */ -#define ERR_CLSD -13 /* Connection closed. */ -#define ERR_CONN -14 /* Not connected. */ - -#define ERR_ARG -15 /* Illegal argument. */ - -#define ERR_IF -16 /* Low-level netif error */ -#else -#define ERR_ISCONN -9 /* Already connected. */ - -#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) - -#define ERR_ABRT -10 /* Connection aborted. */ -#define ERR_RST -11 /* Connection reset. */ -#define ERR_CLSD -12 /* Connection closed. */ -#define ERR_CONN -13 /* Not connected. */ - -#define ERR_ARG -14 /* Illegal argument. */ - -#define ERR_IF -15 /* Low-level netif error */ -#endif - -#ifdef LWIP_DEBUG -extern const char *lwip_strerr(err_t err); -#else -#define lwip_strerr(x) "" -#endif /* LWIP_DEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_ERR_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ERR_H__ +#define __LWIP_ERR_H__ + +#include "lwip/opt.h" +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Define LWIP_ERR_T in cc.h if you want to use + * a different type for your platform (must be signed). */ +#ifdef LWIP_ERR_T +typedef LWIP_ERR_T err_t; +#else /* LWIP_ERR_T */ +typedef s8_t err_t; +#endif /* LWIP_ERR_T*/ + +/* Definitions for error constants. */ + +#define ERR_OK 0 /* No error, everything OK. */ +#define ERR_MEM -1 /* Out of memory error. */ +#define ERR_BUF -2 /* Buffer error. */ +#define ERR_TIMEOUT -3 /* Timeout. */ +#define ERR_RTE -4 /* Routing problem. */ +#define ERR_INPROGRESS -5 /* Operation in progress */ +#define ERR_VAL -6 /* Illegal value. */ +#define ERR_WOULDBLOCK -7 /* Operation would block. */ +#define ERR_USE -8 /* Address in use. */ + +#ifdef LWIP_ESP8266 +#define ERR_ALREADY -9 /* Already connected. */ +#define ERR_ISCONN -10 /* Conn already established.*/ + +#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) + +#define ERR_ABRT -11 /* Connection aborted. */ +#define ERR_RST -12 /* Connection reset. */ +#define ERR_CLSD -13 /* Connection closed. */ +#define ERR_CONN -14 /* Not connected. */ + +#define ERR_ARG -15 /* Illegal argument. */ + +#define ERR_IF -16 /* Low-level netif error */ +#else +#define ERR_ISCONN -9 /* Already connected. */ + +#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) + +#define ERR_ABRT -10 /* Connection aborted. */ +#define ERR_RST -11 /* Connection reset. */ +#define ERR_CLSD -12 /* Connection closed. */ +#define ERR_CONN -13 /* Not connected. */ + +#define ERR_ARG -14 /* Illegal argument. */ + +#define ERR_IF -15 /* Low-level netif error */ +#endif + +#ifdef LWIP_DEBUG +extern const char *lwip_strerr(err_t err); +#else +#define lwip_strerr(x) "" +#endif /* LWIP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ERR_H__ */ diff --git a/include/lwip/lwip/inet_chksum.h b/include/lwip/lwip/inet_chksum.h index f9a1723a..e1687888 100644 --- a/include/lwip/lwip/inet_chksum.h +++ b/include/lwip/lwip/inet_chksum.h @@ -1,112 +1,112 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_INET_CHKSUM_H__ -#define __LWIP_INET_CHKSUM_H__ - -#include "lwip/opt.h" - -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" - -/** Swap the bytes in an u16_t: much like htons() for little-endian */ -#ifndef SWAP_BYTES_IN_WORD -#if LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) -/* little endian and PLATFORM_BYTESWAP defined */ -#define SWAP_BYTES_IN_WORD(w) LWIP_PLATFORM_HTONS(w) -#else /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) */ -/* can't use htons on big endian (or PLATFORM_BYTESWAP not defined)... */ -#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8) -#endif /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)*/ -#endif /* SWAP_BYTES_IN_WORD */ - -/** Split an u32_t in two u16_ts and add them up */ -#ifndef FOLD_U32T -#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL)) -#endif - -#if LWIP_CHECKSUM_ON_COPY -/** Function-like macro: same as MEMCPY but returns the checksum of copied data - as u16_t */ -#ifndef LWIP_CHKSUM_COPY -#define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len) -#ifndef LWIP_CHKSUM_COPY_ALGORITHM -#define LWIP_CHKSUM_COPY_ALGORITHM 1 -#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ -#endif /* LWIP_CHKSUM_COPY */ -#else /* LWIP_CHECKSUM_ON_COPY */ -#define LWIP_CHKSUM_COPY_ALGORITHM 0 -#endif /* LWIP_CHECKSUM_ON_COPY */ - -#ifdef __cplusplus -extern "C" { -#endif - -u16_t inet_chksum(void *dataptr, u16_t len); -u16_t inet_chksum_pbuf(struct pbuf *p); -u16_t inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - ip_addr_t *src, ip_addr_t *dest); -u16_t inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, - u16_t proto_len, u16_t chksum_len, ip_addr_t *src, ip_addr_t *dest); -#if LWIP_CHKSUM_COPY_ALGORITHM -u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len); -#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ - -#if LWIP_IPV6 -u16_t ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - ip6_addr_t *src, ip6_addr_t *dest); -u16_t ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, ip6_addr_t *src, ip6_addr_t *dest); - -#define ipX_chksum_pseudo(isipv6, p, proto, proto_len, src, dest) \ - ((isipv6) ? \ - ip6_chksum_pseudo(p, proto, proto_len, ipX_2_ip6(src), ipX_2_ip6(dest)) :\ - inet_chksum_pseudo(p, proto, proto_len, ipX_2_ip(src), ipX_2_ip(dest))) -#define ipX_chksum_pseudo_partial(isipv6, p, proto, proto_len, chksum_len, src, dest) \ - ((isipv6) ? \ - ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ipX_2_ip6(src), ipX_2_ip6(dest)) :\ - inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ipX_2_ip(src), ipX_2_ip(dest))) - -#else /* LWIP_IPV6 */ - -#define ipX_chksum_pseudo(isipv6, p, proto, proto_len, src, dest) \ - inet_chksum_pseudo(p, proto, proto_len, src, dest) -#define ipX_chksum_pseudo_partial(isipv6, p, proto, proto_len, chksum_len, src, dest) \ - inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, src, dest) - -#endif /* LWIP_IPV6 */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_INET_H__ */ - +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INET_CHKSUM_H__ +#define __LWIP_INET_CHKSUM_H__ + +#include "lwip/opt.h" + +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +/** Swap the bytes in an u16_t: much like htons() for little-endian */ +#ifndef SWAP_BYTES_IN_WORD +#if LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) +/* little endian and PLATFORM_BYTESWAP defined */ +#define SWAP_BYTES_IN_WORD(w) LWIP_PLATFORM_HTONS(w) +#else /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) */ +/* can't use htons on big endian (or PLATFORM_BYTESWAP not defined)... */ +#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8) +#endif /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)*/ +#endif /* SWAP_BYTES_IN_WORD */ + +/** Split an u32_t in two u16_ts and add them up */ +#ifndef FOLD_U32T +#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL)) +#endif + +#if LWIP_CHECKSUM_ON_COPY +/** Function-like macro: same as MEMCPY but returns the checksum of copied data + as u16_t */ +#ifndef LWIP_CHKSUM_COPY +#define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len) +#ifndef LWIP_CHKSUM_COPY_ALGORITHM +#define LWIP_CHKSUM_COPY_ALGORITHM 1 +#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ +#endif /* LWIP_CHKSUM_COPY */ +#else /* LWIP_CHECKSUM_ON_COPY */ +#define LWIP_CHKSUM_COPY_ALGORITHM 0 +#endif /* LWIP_CHECKSUM_ON_COPY */ + +#ifdef __cplusplus +extern "C" { +#endif + +u16_t inet_chksum(void *dataptr, u16_t len); +u16_t inet_chksum_pbuf(struct pbuf *p); +u16_t inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, + ip_addr_t *src, ip_addr_t *dest); +u16_t inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, + u16_t proto_len, u16_t chksum_len, ip_addr_t *src, ip_addr_t *dest); +#if LWIP_CHKSUM_COPY_ALGORITHM +u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len); +#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ + +#if LWIP_IPV6 +u16_t ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, + ip6_addr_t *src, ip6_addr_t *dest); +u16_t ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, + u16_t chksum_len, ip6_addr_t *src, ip6_addr_t *dest); + +#define ipX_chksum_pseudo(isipv6, p, proto, proto_len, src, dest) \ + ((isipv6) ? \ + ip6_chksum_pseudo(p, proto, proto_len, ipX_2_ip6(src), ipX_2_ip6(dest)) :\ + inet_chksum_pseudo(p, proto, proto_len, ipX_2_ip(src), ipX_2_ip(dest))) +#define ipX_chksum_pseudo_partial(isipv6, p, proto, proto_len, chksum_len, src, dest) \ + ((isipv6) ? \ + ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ipX_2_ip6(src), ipX_2_ip6(dest)) :\ + inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ipX_2_ip(src), ipX_2_ip(dest))) + +#else /* LWIP_IPV6 */ + +#define ipX_chksum_pseudo(isipv6, p, proto, proto_len, src, dest) \ + inet_chksum_pseudo(p, proto, proto_len, src, dest) +#define ipX_chksum_pseudo_partial(isipv6, p, proto, proto_len, chksum_len, src, dest) \ + inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, src, dest) + +#endif /* LWIP_IPV6 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ + diff --git a/include/lwip/lwip/init.h b/include/lwip/lwip/init.h index c9d8300e..4e2e2856 100644 --- a/include/lwip/lwip/init.h +++ b/include/lwip/lwip/init.h @@ -1,72 +1,72 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_INIT_H__ -#define __LWIP_INIT_H__ - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** X.x.x: Major version of the stack */ -#define LWIP_VERSION_MAJOR 1U -/** x.X.x: Minor version of the stack */ -#define LWIP_VERSION_MINOR 4U -/** x.x.X: Revision of the stack */ -#define LWIP_VERSION_REVISION 1U -/** For release candidates, this is set to 1..254 - * For official releases, this is set to 255 (LWIP_RC_RELEASE) - * For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */ -#define LWIP_VERSION_RC 0U - -/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ -#define LWIP_RC_RELEASE 255U -/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for CVS versions */ -#define LWIP_RC_DEVELOPMENT 0U - -#define LWIP_VERSION_IS_RELEASE (LWIP_VERSION_RC == LWIP_RC_RELEASE) -#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT) -#define LWIP_VERSION_IS_RC ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT)) - -/** Provides the version of the stack */ -#define LWIP_VERSION (LWIP_VERSION_MAJOR << 24 | LWIP_VERSION_MINOR << 16 | \ - LWIP_VERSION_REVISION << 8 | LWIP_VERSION_RC) - -/* Modules initialization */ -void lwip_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_INIT_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INIT_H__ +#define __LWIP_INIT_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** X.x.x: Major version of the stack */ +#define LWIP_VERSION_MAJOR 1U +/** x.X.x: Minor version of the stack */ +#define LWIP_VERSION_MINOR 4U +/** x.x.X: Revision of the stack */ +#define LWIP_VERSION_REVISION 1U +/** For release candidates, this is set to 1..254 + * For official releases, this is set to 255 (LWIP_RC_RELEASE) + * For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */ +#define LWIP_VERSION_RC 0U + +/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ +#define LWIP_RC_RELEASE 255U +/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for CVS versions */ +#define LWIP_RC_DEVELOPMENT 0U + +#define LWIP_VERSION_IS_RELEASE (LWIP_VERSION_RC == LWIP_RC_RELEASE) +#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT) +#define LWIP_VERSION_IS_RC ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT)) + +/** Provides the version of the stack */ +#define LWIP_VERSION (LWIP_VERSION_MAJOR << 24 | LWIP_VERSION_MINOR << 16 | \ + LWIP_VERSION_REVISION << 8 | LWIP_VERSION_RC) + +/* Modules initialization */ +void lwip_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INIT_H__ */ diff --git a/include/lwip/lwip/ip.h b/include/lwip/lwip/ip.h index c996954e..a0cd1d4d 100644 --- a/include/lwip/lwip/ip.h +++ b/include/lwip/lwip/ip.h @@ -1,254 +1,254 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_IP_H__ -#define __LWIP_IP_H__ - -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" -#include "lwip/netif.h" -#include "lwip/ip4.h" -#include "lwip/ip6.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* This is passed as the destination address to ip_output_if (not - to ip_output), meaning that an IP header already is constructed - in the pbuf. This is used when TCP retransmits. */ -#ifdef IP_HDRINCL -#undef IP_HDRINCL -#endif /* IP_HDRINCL */ -#define IP_HDRINCL NULL - -#if LWIP_NETIF_HWADDRHINT -#define IP_PCB_ADDRHINT ;u8_t addr_hint -#else -#define IP_PCB_ADDRHINT -#endif /* LWIP_NETIF_HWADDRHINT */ - -#if LWIP_IPV6 -#define IP_PCB_ISIPV6_MEMBER u8_t isipv6; -#define IP_PCB_IPVER_EQ(pcb1, pcb2) ((pcb1)->isipv6 == (pcb2)->isipv6) -#define IP_PCB_IPVER_INPUT_MATCH(pcb) (ip_current_is_v6() ? \ - ((pcb)->isipv6 != 0) : \ - ((pcb)->isipv6 == 0)) -#define PCB_ISIPV6(pcb) ((pcb)->isipv6) -#else -#define IP_PCB_ISIPV6_MEMBER -#define IP_PCB_IPVER_EQ(pcb1, pcb2) 1 -#define IP_PCB_IPVER_INPUT_MATCH(pcb) 1 -#define PCB_ISIPV6(pcb) 0 -#endif /* LWIP_IPV6 */ - -/* This is the common part of all PCB types. It needs to be at the - beginning of a PCB type definition. It is located here so that - changes to this common part are made in one location instead of - having to change all PCB structs. */ -#define IP_PCB \ - IP_PCB_ISIPV6_MEMBER \ - /* ip addresses in network byte order */ \ - ipX_addr_t local_ip; \ - ipX_addr_t remote_ip; \ - /* Socket options */ \ - u8_t so_options; \ - /* Type Of Service */ \ - u8_t tos; \ - /* Time To Live */ \ - u8_t ttl \ - /* link layer address resolution hint */ \ - IP_PCB_ADDRHINT - -struct ip_pcb { -/* Common members of all PCB types */ - IP_PCB; -}; - -/* - * Option flags per-socket. These are the same like SO_XXX. - */ -/*#define SOF_DEBUG 0x01U Unimplemented: turn on debugging info recording */ -#define SOF_ACCEPTCONN 0x02U /* socket has had listen() */ -#define SOF_REUSEADDR 0x04U /* allow local address reuse */ -#define SOF_KEEPALIVE 0x08U /* keep connections alive */ -/*#define SOF_DONTROUTE 0x10U Unimplemented: just use interface addresses */ -#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ -/*#define SOF_USELOOPBACK 0x40U Unimplemented: bypass hardware when possible */ -#define SOF_LINGER 0x80U /* linger on close if data present */ -/*#define SOF_OOBINLINE 0x0100U Unimplemented: leave received OOB data in line */ -/*#define SOF_REUSEPORT 0x0200U Unimplemented: allow local address & port reuse */ - -/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ -#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/) - -/* Global variables of this module, kept in a struct for efficient access using base+index. */ -struct ip_globals -{ - /** The interface that provided the packet for the current callback invocation. */ - struct netif *current_netif; - /** Header of the input packet currently being processed. */ - const struct ip_hdr *current_ip4_header; -#if LWIP_IPV6 - /** Header of the input IPv6 packet currently being processed. */ - const struct ip6_hdr *current_ip6_header; -#endif /* LWIP_IPV6 */ - /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */ - u16_t current_ip_header_tot_len; - /** Source IP address of current_header */ - ipX_addr_t current_iphdr_src; - /** Destination IP address of current_header */ - ipX_addr_t current_iphdr_dest; -}; -extern struct ip_globals ip_data; - - -/** Get the interface that received the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip_current_netif() (ip_data.current_netif) -/** Get the IP header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip_current_header() (ip_data.current_ip4_header) -/** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */ -#define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len) -/** Source IP address of current_header */ -#define ipX_current_src_addr() (&ip_data.current_iphdr_src) -/** Destination IP address of current_header */ -#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) - -#if LWIP_IPV6 -/** Get the IPv6 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip6_current_header() (ip_data.current_ip6_header) -/** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */ -#define ip_current_is_v6() (ip6_current_header() != NULL) -/** Source IPv6 address of current_header */ -#define ip6_current_src_addr() (ipX_2_ip6(&ip_data.current_iphdr_src)) -/** Destination IPv6 address of current_header */ -#define ip6_current_dest_addr() (ipX_2_ip6(&ip_data.current_iphdr_dest)) -/** Get the transport layer protocol */ -#define ip_current_header_proto() (ip_current_is_v6() ? \ - IP6H_NEXTH(ip6_current_header()) :\ - IPH_PROTO(ip_current_header())) -/** Get the transport layer header */ -#define ipX_next_header_ptr() ((void*)((ip_current_is_v6() ? \ - (u8_t*)ip6_current_header() : (u8_t*)ip_current_header()) + ip_current_header_tot_len())) - -/** Set an IP_PCB to IPv6 (IPv4 is the default) */ -#define ip_set_v6(pcb, val) do{if(pcb != NULL) { pcb->isipv6 = val; }}while(0) - -/** Source IP4 address of current_header */ -#define ip_current_src_addr() (ipX_2_ip(&ip_data.current_iphdr_src)) -/** Destination IP4 address of current_header */ -#define ip_current_dest_addr() (ipX_2_ip(&ip_data.current_iphdr_dest)) - -#else /* LWIP_IPV6 */ - -/** Always returns FALSE when only supporting IPv4 */ -#define ip_current_is_v6() 0 -/** Get the transport layer protocol */ -#define ip_current_header_proto() IPH_PROTO(ip_current_header()) -/** Get the transport layer header */ -#define ipX_next_header_ptr() ((void*)((u8_t*)ip_current_header() + ip_current_header_tot_len())) -/** Source IP4 address of current_header */ -#define ip_current_src_addr() (&ip_data.current_iphdr_src) -/** Destination IP4 address of current_header */ -#define ip_current_dest_addr() (&ip_data.current_iphdr_dest) - -#endif /* LWIP_IPV6 */ - -/** Union source address of current_header */ -#define ipX_current_src_addr() (&ip_data.current_iphdr_src) -/** Union destination address of current_header */ -#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) - -/** Gets an IP pcb option (SOF_* flags) */ -#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) -/** Sets an IP pcb option (SOF_* flags) */ -#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt)) -/** Resets an IP pcb option (SOF_* flags) */ -#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt)) - -#if LWIP_IPV6 -#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ - ((isipv6) ? \ - ip6_output(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto) : \ - ip_output(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto)) -#define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ - ((isipv6) ? \ - ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ - ip_output_if(p, (src), (dest), ttl, tos, proto, netif)) -#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ - ((isipv6) ? \ - ip6_output_hinted(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto, addr_hint) : \ - ip_output_hinted(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto, addr_hint)) -#define ipX_route(isipv6, src, dest) \ - ((isipv6) ? \ - ip6_route(ipX_2_ip6(src), ipX_2_ip6(dest)) : \ - ip_route(ipX_2_ip(dest))) -#define ipX_netif_get_local_ipX(isipv6, netif, dest) \ - ((isipv6) ? \ - ip6_netif_get_local_ipX(netif, ipX_2_ip6(dest)) : \ - ip_netif_get_local_ipX(netif)) -#define ipX_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip_debug_print(p)) -#else /* LWIP_IPV6 */ -#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ - ip_output(p, src, dest, ttl, tos, proto) -#define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ - ip_output_if(p, src, dest, ttl, tos, proto, netif) -#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ - ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) -#define ipX_route(isipv6, src, dest) \ - ip_route(ipX_2_ip(dest)) -#define ipX_netif_get_local_ipX(isipv6, netif, dest) \ - ip_netif_get_local_ipX(netif) -#define ipX_debug_print(is_ipv6, p) ip_debug_print(p) -#endif /* LWIP_IPV6 */ - -#define ipX_route_get_local_ipX(isipv6, src, dest, netif, ipXaddr) do { \ - (netif) = ipX_route(isipv6, src, dest); \ - (ipXaddr) = ipX_netif_get_local_ipX(isipv6, netif, dest); \ -}while(0) - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP_H__ */ - - +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_H__ +#define __LWIP_IP_H__ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/netif.h" +#include "lwip/ip4.h" +#include "lwip/ip6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is passed as the destination address to ip_output_if (not + to ip_output), meaning that an IP header already is constructed + in the pbuf. This is used when TCP retransmits. */ +#ifdef IP_HDRINCL +#undef IP_HDRINCL +#endif /* IP_HDRINCL */ +#define IP_HDRINCL NULL + +#if LWIP_NETIF_HWADDRHINT +#define IP_PCB_ADDRHINT ;u8_t addr_hint +#else +#define IP_PCB_ADDRHINT +#endif /* LWIP_NETIF_HWADDRHINT */ + +#if LWIP_IPV6 +#define IP_PCB_ISIPV6_MEMBER u8_t isipv6; +#define IP_PCB_IPVER_EQ(pcb1, pcb2) ((pcb1)->isipv6 == (pcb2)->isipv6) +#define IP_PCB_IPVER_INPUT_MATCH(pcb) (ip_current_is_v6() ? \ + ((pcb)->isipv6 != 0) : \ + ((pcb)->isipv6 == 0)) +#define PCB_ISIPV6(pcb) ((pcb)->isipv6) +#else +#define IP_PCB_ISIPV6_MEMBER +#define IP_PCB_IPVER_EQ(pcb1, pcb2) 1 +#define IP_PCB_IPVER_INPUT_MATCH(pcb) 1 +#define PCB_ISIPV6(pcb) 0 +#endif /* LWIP_IPV6 */ + +/* This is the common part of all PCB types. It needs to be at the + beginning of a PCB type definition. It is located here so that + changes to this common part are made in one location instead of + having to change all PCB structs. */ +#define IP_PCB \ + IP_PCB_ISIPV6_MEMBER \ + /* ip addresses in network byte order */ \ + ipX_addr_t local_ip; \ + ipX_addr_t remote_ip; \ + /* Socket options */ \ + u8_t so_options; \ + /* Type Of Service */ \ + u8_t tos; \ + /* Time To Live */ \ + u8_t ttl \ + /* link layer address resolution hint */ \ + IP_PCB_ADDRHINT + +struct ip_pcb { +/* Common members of all PCB types */ + IP_PCB; +}; + +/* + * Option flags per-socket. These are the same like SO_XXX. + */ +/*#define SOF_DEBUG 0x01U Unimplemented: turn on debugging info recording */ +#define SOF_ACCEPTCONN 0x02U /* socket has had listen() */ +#define SOF_REUSEADDR 0x04U /* allow local address reuse */ +#define SOF_KEEPALIVE 0x08U /* keep connections alive */ +/*#define SOF_DONTROUTE 0x10U Unimplemented: just use interface addresses */ +#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ +/*#define SOF_USELOOPBACK 0x40U Unimplemented: bypass hardware when possible */ +#define SOF_LINGER 0x80U /* linger on close if data present */ +/*#define SOF_OOBINLINE 0x0100U Unimplemented: leave received OOB data in line */ +/*#define SOF_REUSEPORT 0x0200U Unimplemented: allow local address & port reuse */ + +/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ +#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/) + +/* Global variables of this module, kept in a struct for efficient access using base+index. */ +struct ip_globals +{ + /** The interface that provided the packet for the current callback invocation. */ + struct netif *current_netif; + /** Header of the input packet currently being processed. */ + const struct ip_hdr *current_ip4_header; +#if LWIP_IPV6 + /** Header of the input IPv6 packet currently being processed. */ + const struct ip6_hdr *current_ip6_header; +#endif /* LWIP_IPV6 */ + /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */ + u16_t current_ip_header_tot_len; + /** Source IP address of current_header */ + ipX_addr_t current_iphdr_src; + /** Destination IP address of current_header */ + ipX_addr_t current_iphdr_dest; +}; +extern struct ip_globals ip_data; + + +/** Get the interface that received the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_netif() (ip_data.current_netif) +/** Get the IP header of the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_header() (ip_data.current_ip4_header) +/** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */ +#define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len) +/** Source IP address of current_header */ +#define ipX_current_src_addr() (&ip_data.current_iphdr_src) +/** Destination IP address of current_header */ +#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) + +#if LWIP_IPV6 +/** Get the IPv6 header of the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip6_current_header() (ip_data.current_ip6_header) +/** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */ +#define ip_current_is_v6() (ip6_current_header() != NULL) +/** Source IPv6 address of current_header */ +#define ip6_current_src_addr() (ipX_2_ip6(&ip_data.current_iphdr_src)) +/** Destination IPv6 address of current_header */ +#define ip6_current_dest_addr() (ipX_2_ip6(&ip_data.current_iphdr_dest)) +/** Get the transport layer protocol */ +#define ip_current_header_proto() (ip_current_is_v6() ? \ + IP6H_NEXTH(ip6_current_header()) :\ + IPH_PROTO(ip_current_header())) +/** Get the transport layer header */ +#define ipX_next_header_ptr() ((void*)((ip_current_is_v6() ? \ + (u8_t*)ip6_current_header() : (u8_t*)ip_current_header()) + ip_current_header_tot_len())) + +/** Set an IP_PCB to IPv6 (IPv4 is the default) */ +#define ip_set_v6(pcb, val) do{if(pcb != NULL) { pcb->isipv6 = val; }}while(0) + +/** Source IP4 address of current_header */ +#define ip_current_src_addr() (ipX_2_ip(&ip_data.current_iphdr_src)) +/** Destination IP4 address of current_header */ +#define ip_current_dest_addr() (ipX_2_ip(&ip_data.current_iphdr_dest)) + +#else /* LWIP_IPV6 */ + +/** Always returns FALSE when only supporting IPv4 */ +#define ip_current_is_v6() 0 +/** Get the transport layer protocol */ +#define ip_current_header_proto() IPH_PROTO(ip_current_header()) +/** Get the transport layer header */ +#define ipX_next_header_ptr() ((void*)((u8_t*)ip_current_header() + ip_current_header_tot_len())) +/** Source IP4 address of current_header */ +#define ip_current_src_addr() (&ip_data.current_iphdr_src) +/** Destination IP4 address of current_header */ +#define ip_current_dest_addr() (&ip_data.current_iphdr_dest) + +#endif /* LWIP_IPV6 */ + +/** Union source address of current_header */ +#define ipX_current_src_addr() (&ip_data.current_iphdr_src) +/** Union destination address of current_header */ +#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) + +/** Gets an IP pcb option (SOF_* flags) */ +#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) +/** Sets an IP pcb option (SOF_* flags) */ +#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt)) +/** Resets an IP pcb option (SOF_* flags) */ +#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt)) + +#if LWIP_IPV6 +#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ + ((isipv6) ? \ + ip6_output(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto) : \ + ip_output(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto)) +#define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ + ((isipv6) ? \ + ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ + ip_output_if(p, (src), (dest), ttl, tos, proto, netif)) +#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ + ((isipv6) ? \ + ip6_output_hinted(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto, addr_hint) : \ + ip_output_hinted(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto, addr_hint)) +#define ipX_route(isipv6, src, dest) \ + ((isipv6) ? \ + ip6_route(ipX_2_ip6(src), ipX_2_ip6(dest)) : \ + ip_route(ipX_2_ip(dest))) +#define ipX_netif_get_local_ipX(isipv6, netif, dest) \ + ((isipv6) ? \ + ip6_netif_get_local_ipX(netif, ipX_2_ip6(dest)) : \ + ip_netif_get_local_ipX(netif)) +#define ipX_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip_debug_print(p)) +#else /* LWIP_IPV6 */ +#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ + ip_output(p, src, dest, ttl, tos, proto) +#define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ + ip_output_if(p, src, dest, ttl, tos, proto, netif) +#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ + ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) +#define ipX_route(isipv6, src, dest) \ + ip_route(ipX_2_ip(dest)) +#define ipX_netif_get_local_ipX(isipv6, netif, dest) \ + ip_netif_get_local_ipX(netif) +#define ipX_debug_print(is_ipv6, p) ip_debug_print(p) +#endif /* LWIP_IPV6 */ + +#define ipX_route_get_local_ipX(isipv6, src, dest, netif, ipXaddr) do { \ + (netif) = ipX_route(isipv6, src, dest); \ + (ipXaddr) = ipX_netif_get_local_ipX(isipv6, netif, dest); \ +}while(0) + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_H__ */ + + diff --git a/include/lwip/lwip/ip_addr.h b/include/lwip/lwip/ip_addr.h index a78fef60..7bd03cbd 100644 --- a/include/lwip/lwip/ip_addr.h +++ b/include/lwip/lwip/ip_addr.h @@ -1,130 +1,130 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_IP_ADDR_H__ -#define __LWIP_IP_ADDR_H__ - -#include "lwip/opt.h" -#include "lwip/def.h" - -#include "lwip/ip4_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_IPV6 -/* A union struct for both IP version's addresses. */ -typedef union { - ip_addr_t ip4; - ip6_addr_t ip6; -} ipX_addr_t; - -/** These functions only exist for type-safe conversion from ip_addr_t to - ip6_addr_t and back */ -#ifdef LWIP_ALLOW_STATIC_FN_IN_HEADER -static ip6_addr_t* ip_2_ip6(ip_addr_t *ipaddr) -{ return (ip6_addr_t*)ipaddr;} -static ip_addr_t* ip6_2_ip(ip6_addr_t *ip6addr) -{ return (ip_addr_t*)ip6addr; } -static ipX_addr_t* ip_2_ipX(ip_addr_t *ipaddr) -{ return (ipX_addr_t*)ipaddr; } -static ipX_addr_t* ip6_2_ipX(ip6_addr_t *ip6addr) -{ return (ipX_addr_t*)ip6addr; } -#else /* LWIP_ALLOW_STATIC_FN_IN_HEADER */ -#define ip_2_ip6(ipaddr) ((ip6_addr_t*)(ipaddr)) -#define ip6_2_ip(ip6addr) ((ip_addr_t*)(ip6addr)) -#define ip_2_ipX(ipaddr) ((ipX_addr_t*)ipaddr) -#define ip6_2_ipX(ip6addr) ((ipX_addr_t*)ip6addr) -#endif /* LWIP_ALLOW_STATIC_FN_IN_HEADER*/ -#define ipX_2_ip6(ip6addr) (&((ip6addr)->ip6)) -#define ipX_2_ip(ipaddr) (&((ipaddr)->ip4)) - -#define ipX_addr_copy(is_ipv6, dest, src) do{if(is_ipv6){ \ - ip6_addr_copy((dest).ip6, (src).ip6); }else{ \ - ip_addr_copy((dest).ip4, (src).ip4); }}while(0) -#define ipX_addr_set(is_ipv6, dest, src) do{if(is_ipv6){ \ - ip6_addr_set(ipX_2_ip6(dest), ipX_2_ip6(src)); }else{ \ - ip_addr_set(ipX_2_ip(dest), ipX_2_ip(src)); }}while(0) -#define ipX_addr_set_ipaddr(is_ipv6, dest, src) do{if(is_ipv6){ \ - ip6_addr_set(ipX_2_ip6(dest), ip_2_ip6(src)); }else{ \ - ip_addr_set(ipX_2_ip(dest), src); }}while(0) -#define ipX_addr_set_zero(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_zero(ipX_2_ip6(ipaddr)); }else{ \ - ip_addr_set_zero(ipX_2_ip(ipaddr)); }}while(0) -#define ipX_addr_set_any(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_any(ipX_2_ip6(ipaddr)); }else{ \ - ip_addr_set_any(ipX_2_ip(ipaddr)); }}while(0) -#define ipX_addr_set_loopback(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_loopback(ipX_2_ip6(ipaddr)); }else{ \ - ip_addr_set_loopback(ipX_2_ip(ipaddr)); }}while(0) -#define ipX_addr_set_hton(is_ipv6, dest, src) do{if(is_ipv6){ \ - ip6_addr_set_hton(ipX_2_ip6(ipaddr), (src)) ;}else{ \ - ip_addr_set_hton(ipX_2_ip(ipaddr), (src));}}while(0) -#define ipX_addr_cmp(is_ipv6, addr1, addr2) ((is_ipv6) ? \ - ip6_addr_cmp(ipX_2_ip6(addr1), ipX_2_ip6(addr2)) : \ - ip_addr_cmp(ipX_2_ip(addr1), ipX_2_ip(addr2))) -#define ipX_addr_isany(is_ipv6, ipaddr) ((is_ipv6) ? \ - ip6_addr_isany(ipX_2_ip6(ipaddr)) : \ - ip_addr_isany(ipX_2_ip(ipaddr))) -#define ipX_addr_ismulticast(is_ipv6, ipaddr) ((is_ipv6) ? \ - ip6_addr_ismulticast(ipX_2_ip6(ipaddr)) : \ - ip_addr_ismulticast(ipX_2_ip(ipaddr))) -#define ipX_addr_debug_print(is_ipv6, debug, ipaddr) do { if(is_ipv6) { \ - ip6_addr_debug_print(debug, ipX_2_ip6(ipaddr)); } else { \ - ip_addr_debug_print(debug, ipX_2_ip(ipaddr)); }}while(0) - -#else /* LWIP_IPV6 */ - -typedef ip_addr_t ipX_addr_t; -#define ipX_2_ip(ipaddr) (ipaddr) -#define ip_2_ipX(ipaddr) (ipaddr) - -#define ipX_addr_copy(is_ipv6, dest, src) ip_addr_copy(dest, src) -#define ipX_addr_set(is_ipv6, dest, src) ip_addr_set(dest, src) -#define ipX_addr_set_ipaddr(is_ipv6, dest, src) ip_addr_set(dest, src) -#define ipX_addr_set_zero(is_ipv6, ipaddr) ip_addr_set_zero(ipaddr) -#define ipX_addr_set_any(is_ipv6, ipaddr) ip_addr_set_any(ipaddr) -#define ipX_addr_set_loopback(is_ipv6, ipaddr) ip_addr_set_loopback(ipaddr) -#define ipX_addr_set_hton(is_ipv6, dest, src) ip_addr_set_hton(dest, src) -#define ipX_addr_cmp(is_ipv6, addr1, addr2) ip_addr_cmp(addr1, addr2) -#define ipX_addr_isany(is_ipv6, ipaddr) ip_addr_isany(ipaddr) -#define ipX_addr_ismulticast(is_ipv6, ipaddr) ip_addr_ismulticast(ipaddr) -#define ipX_addr_debug_print(is_ipv6, debug, ipaddr) ip_addr_debug_print(debug, ipaddr) - -#endif /* LWIP_IPV6 */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_IP_ADDR_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_ADDR_H__ +#define __LWIP_IP_ADDR_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" + +#include "lwip/ip4_addr.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_IPV6 +/* A union struct for both IP version's addresses. */ +typedef union { + ip_addr_t ip4; + ip6_addr_t ip6; +} ipX_addr_t; + +/** These functions only exist for type-safe conversion from ip_addr_t to + ip6_addr_t and back */ +#ifdef LWIP_ALLOW_STATIC_FN_IN_HEADER +static ip6_addr_t* ip_2_ip6(ip_addr_t *ipaddr) +{ return (ip6_addr_t*)ipaddr;} +static ip_addr_t* ip6_2_ip(ip6_addr_t *ip6addr) +{ return (ip_addr_t*)ip6addr; } +static ipX_addr_t* ip_2_ipX(ip_addr_t *ipaddr) +{ return (ipX_addr_t*)ipaddr; } +static ipX_addr_t* ip6_2_ipX(ip6_addr_t *ip6addr) +{ return (ipX_addr_t*)ip6addr; } +#else /* LWIP_ALLOW_STATIC_FN_IN_HEADER */ +#define ip_2_ip6(ipaddr) ((ip6_addr_t*)(ipaddr)) +#define ip6_2_ip(ip6addr) ((ip_addr_t*)(ip6addr)) +#define ip_2_ipX(ipaddr) ((ipX_addr_t*)ipaddr) +#define ip6_2_ipX(ip6addr) ((ipX_addr_t*)ip6addr) +#endif /* LWIP_ALLOW_STATIC_FN_IN_HEADER*/ +#define ipX_2_ip6(ip6addr) (&((ip6addr)->ip6)) +#define ipX_2_ip(ipaddr) (&((ipaddr)->ip4)) + +#define ipX_addr_copy(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_copy((dest).ip6, (src).ip6); }else{ \ + ip_addr_copy((dest).ip4, (src).ip4); }}while(0) +#define ipX_addr_set(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_set(ipX_2_ip6(dest), ipX_2_ip6(src)); }else{ \ + ip_addr_set(ipX_2_ip(dest), ipX_2_ip(src)); }}while(0) +#define ipX_addr_set_ipaddr(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_set(ipX_2_ip6(dest), ip_2_ip6(src)); }else{ \ + ip_addr_set(ipX_2_ip(dest), src); }}while(0) +#define ipX_addr_set_zero(is_ipv6, ipaddr) do{if(is_ipv6){ \ + ip6_addr_set_zero(ipX_2_ip6(ipaddr)); }else{ \ + ip_addr_set_zero(ipX_2_ip(ipaddr)); }}while(0) +#define ipX_addr_set_any(is_ipv6, ipaddr) do{if(is_ipv6){ \ + ip6_addr_set_any(ipX_2_ip6(ipaddr)); }else{ \ + ip_addr_set_any(ipX_2_ip(ipaddr)); }}while(0) +#define ipX_addr_set_loopback(is_ipv6, ipaddr) do{if(is_ipv6){ \ + ip6_addr_set_loopback(ipX_2_ip6(ipaddr)); }else{ \ + ip_addr_set_loopback(ipX_2_ip(ipaddr)); }}while(0) +#define ipX_addr_set_hton(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_set_hton(ipX_2_ip6(ipaddr), (src)) ;}else{ \ + ip_addr_set_hton(ipX_2_ip(ipaddr), (src));}}while(0) +#define ipX_addr_cmp(is_ipv6, addr1, addr2) ((is_ipv6) ? \ + ip6_addr_cmp(ipX_2_ip6(addr1), ipX_2_ip6(addr2)) : \ + ip_addr_cmp(ipX_2_ip(addr1), ipX_2_ip(addr2))) +#define ipX_addr_isany(is_ipv6, ipaddr) ((is_ipv6) ? \ + ip6_addr_isany(ipX_2_ip6(ipaddr)) : \ + ip_addr_isany(ipX_2_ip(ipaddr))) +#define ipX_addr_ismulticast(is_ipv6, ipaddr) ((is_ipv6) ? \ + ip6_addr_ismulticast(ipX_2_ip6(ipaddr)) : \ + ip_addr_ismulticast(ipX_2_ip(ipaddr))) +#define ipX_addr_debug_print(is_ipv6, debug, ipaddr) do { if(is_ipv6) { \ + ip6_addr_debug_print(debug, ipX_2_ip6(ipaddr)); } else { \ + ip_addr_debug_print(debug, ipX_2_ip(ipaddr)); }}while(0) + +#else /* LWIP_IPV6 */ + +typedef ip_addr_t ipX_addr_t; +#define ipX_2_ip(ipaddr) (ipaddr) +#define ip_2_ipX(ipaddr) (ipaddr) + +#define ipX_addr_copy(is_ipv6, dest, src) ip_addr_copy(dest, src) +#define ipX_addr_set(is_ipv6, dest, src) ip_addr_set(dest, src) +#define ipX_addr_set_ipaddr(is_ipv6, dest, src) ip_addr_set(dest, src) +#define ipX_addr_set_zero(is_ipv6, ipaddr) ip_addr_set_zero(ipaddr) +#define ipX_addr_set_any(is_ipv6, ipaddr) ip_addr_set_any(ipaddr) +#define ipX_addr_set_loopback(is_ipv6, ipaddr) ip_addr_set_loopback(ipaddr) +#define ipX_addr_set_hton(is_ipv6, dest, src) ip_addr_set_hton(dest, src) +#define ipX_addr_cmp(is_ipv6, addr1, addr2) ip_addr_cmp(addr1, addr2) +#define ipX_addr_isany(is_ipv6, ipaddr) ip_addr_isany(ipaddr) +#define ipX_addr_ismulticast(is_ipv6, ipaddr) ip_addr_ismulticast(ipaddr) +#define ipX_addr_debug_print(is_ipv6, debug, ipaddr) ip_addr_debug_print(debug, ipaddr) + +#endif /* LWIP_IPV6 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/include/lwip/lwip/mem.h b/include/lwip/lwip/mem.h old mode 100755 new mode 100644 index a90dd023..0fdaf73c --- a/include/lwip/lwip/mem.h +++ b/include/lwip/lwip/mem.h @@ -1,159 +1,159 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_MEM_H__ -#define __LWIP_MEM_H__ - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if MEM_LIBC_MALLOC - -#include /* for size_t */ - -typedef size_t mem_size_t; -#define MEM_SIZE_F SZT_F - -/* aliases for C library malloc() */ -#define mem_init() -/* in case C library malloc() needs extra protection, - * allow these defines to be overridden. - */ - -#ifndef MEMLEAK_DEBUG - -#include "esp_libc.h" - -#ifndef mem_free -#define mem_free(s) free(s) -#endif -#ifndef mem_malloc -#define mem_malloc(s) malloc(s) -#endif -#ifndef mem_calloc -#define mem_calloc(s) calloc(s) -#endif -#ifndef mem_realloc -#define mem_realloc(p, s) realloc(p, s) -#endif -#ifndef mem_zalloc -#define mem_zalloc(s) zalloc(s) -#endif - -#else - -#ifndef mem_free -#define mem_free(s) \ - do{\ - const char *file = mem_debug_file;\ - vPortFree(s, file, __LINE__);\ - }while(0) -#endif -#ifndef mem_malloc -#define mem_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__);}) -#endif -#ifndef mem_calloc -#define mem_calloc(s) ({const char *file = mem_debug_file; pvPortCalloc(s, file, __LINE__);}) -#endif -#ifndef mem_realloc -#define mem_realloc(p, s) ({const char *file = mem_debug_file; pvPortRealloc(p, s, file, __LINE__);}) -#endif -#ifndef mem_zalloc -#define mem_zalloc(s) ({const char *file = mem_debug_file; pvPortZalloc(s, file, __LINE__);}) -#endif - -#endif - -/* Since there is no C library allocation function to shrink memory without - moving it, define this to nothing. */ -#ifndef mem_trim -#define mem_trim(mem, size) (mem) -#endif -#else /* MEM_LIBC_MALLOC */ - -/* MEM_SIZE would have to be aligned, but using 64000 here instead of - * 65535 leaves some room for alignment... - */ -#if MEM_SIZE > 64000L -typedef u32_t mem_size_t; -#define MEM_SIZE_F U32_F -#else -typedef u16_t mem_size_t; -#define MEM_SIZE_F U16_F -#endif /* MEM_SIZE > 64000 */ - -#if MEM_USE_POOLS -/** mem_init is not used when using pools instead of a heap */ -#define mem_init() -/** mem_trim is not used when using pools instead of a heap: - we can't free part of a pool element and don't want to copy the rest */ -#define mem_trim(mem, size) (mem) -#else /* MEM_USE_POOLS */ -/* lwIP alternative malloc */ -void mem_init(void); -void *mem_trim(void *mem, mem_size_t size); -#endif /* MEM_USE_POOLS */ -void *mem_malloc(mem_size_t size); -void *mem_calloc(mem_size_t count, mem_size_t size); -void mem_free(void *mem); -#endif /* MEM_LIBC_MALLOC */ - -/** Calculate memory size for an aligned buffer - returns the next highest - * multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and - * LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4). - */ -#ifndef LWIP_MEM_ALIGN_SIZE -#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1)) -#endif - -/** Calculate safe memory size for an aligned buffer when using an unaligned - * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the - * start (e.g. if buffer is u8_t[] and actual data will be u32_t*) - */ -#ifndef LWIP_MEM_ALIGN_BUFFER -#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1)) -#endif - -/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT - * so that ADDR % MEM_ALIGNMENT == 0 - */ -#ifndef LWIP_MEM_ALIGN -#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1))) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_MEM_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_MEM_H__ +#define __LWIP_MEM_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if MEM_LIBC_MALLOC + +#include /* for size_t */ + +typedef size_t mem_size_t; +#define MEM_SIZE_F SZT_F + +/* aliases for C library malloc() */ +#define mem_init() +/* in case C library malloc() needs extra protection, + * allow these defines to be overridden. + */ + +#ifndef MEMLEAK_DEBUG + +#include "esp_libc.h" + +#ifndef mem_free +#define mem_free(s) free(s) +#endif +#ifndef mem_malloc +#define mem_malloc(s) malloc(s) +#endif +#ifndef mem_calloc +#define mem_calloc(s) calloc(s) +#endif +#ifndef mem_realloc +#define mem_realloc(p, s) realloc(p, s) +#endif +#ifndef mem_zalloc +#define mem_zalloc(s) zalloc(s) +#endif + +#else + +#ifndef mem_free +#define mem_free(s) \ + do{\ + const char *file = mem_debug_file;\ + vPortFree(s, file, __LINE__);\ + }while(0) +#endif +#ifndef mem_malloc +#define mem_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__);}) +#endif +#ifndef mem_calloc +#define mem_calloc(s) ({const char *file = mem_debug_file; pvPortCalloc(s, file, __LINE__);}) +#endif +#ifndef mem_realloc +#define mem_realloc(p, s) ({const char *file = mem_debug_file; pvPortRealloc(p, s, file, __LINE__);}) +#endif +#ifndef mem_zalloc +#define mem_zalloc(s) ({const char *file = mem_debug_file; pvPortZalloc(s, file, __LINE__);}) +#endif + +#endif + +/* Since there is no C library allocation function to shrink memory without + moving it, define this to nothing. */ +#ifndef mem_trim +#define mem_trim(mem, size) (mem) +#endif +#else /* MEM_LIBC_MALLOC */ + +/* MEM_SIZE would have to be aligned, but using 64000 here instead of + * 65535 leaves some room for alignment... + */ +#if MEM_SIZE > 64000L +typedef u32_t mem_size_t; +#define MEM_SIZE_F U32_F +#else +typedef u16_t mem_size_t; +#define MEM_SIZE_F U16_F +#endif /* MEM_SIZE > 64000 */ + +#if MEM_USE_POOLS +/** mem_init is not used when using pools instead of a heap */ +#define mem_init() +/** mem_trim is not used when using pools instead of a heap: + we can't free part of a pool element and don't want to copy the rest */ +#define mem_trim(mem, size) (mem) +#else /* MEM_USE_POOLS */ +/* lwIP alternative malloc */ +void mem_init(void); +void *mem_trim(void *mem, mem_size_t size); +#endif /* MEM_USE_POOLS */ +void *mem_malloc(mem_size_t size); +void *mem_calloc(mem_size_t count, mem_size_t size); +void mem_free(void *mem); +#endif /* MEM_LIBC_MALLOC */ + +/** Calculate memory size for an aligned buffer - returns the next highest + * multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and + * LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4). + */ +#ifndef LWIP_MEM_ALIGN_SIZE +#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1)) +#endif + +/** Calculate safe memory size for an aligned buffer when using an unaligned + * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the + * start (e.g. if buffer is u8_t[] and actual data will be u32_t*) + */ +#ifndef LWIP_MEM_ALIGN_BUFFER +#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1)) +#endif + +/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT + * so that ADDR % MEM_ALIGNMENT == 0 + */ +#ifndef LWIP_MEM_ALIGN +#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1))) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_MEM_H__ */ diff --git a/include/lwip/lwip/memp.h b/include/lwip/lwip/memp.h index a810640b..e76471c1 100644 --- a/include/lwip/lwip/memp.h +++ b/include/lwip/lwip/memp.h @@ -1,116 +1,116 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef __LWIP_MEMP_H__ -#define __LWIP_MEMP_H__ - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */ -typedef enum { -#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name, -#include "lwip/memp_std.h" - MEMP_MAX -} memp_t; - -#if MEM_USE_POOLS -/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */ -typedef enum { - /* Get the first (via: - MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/ - MEMP_POOL_HELPER_FIRST = ((u8_t) -#define LWIP_MEMPOOL(name,num,size,desc) -#define LWIP_MALLOC_MEMPOOL_START 1 -#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0 -#define LWIP_MALLOC_MEMPOOL_END -#include "lwip/memp_std.h" - ) , - /* Get the last (via: - MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */ - MEMP_POOL_HELPER_LAST = ((u8_t) -#define LWIP_MEMPOOL(name,num,size,desc) -#define LWIP_MALLOC_MEMPOOL_START -#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size * -#define LWIP_MALLOC_MEMPOOL_END 1 -#include "lwip/memp_std.h" - ) -} memp_pool_helper_t; - -/* The actual start and stop values are here (cast them over) - We use this helper type and these defines so we can avoid using const memp_t values */ -#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST) -#define MEMP_POOL_LAST ((memp_t) MEMP_POOL_HELPER_LAST) -#endif /* MEM_USE_POOLS */ - -#if MEMP_MEM_MALLOC || MEM_USE_POOLS -extern const u32_t memp_sizes[MEMP_MAX]; -#endif /* MEMP_MEM_MALLOC || MEM_USE_POOLS */ - -#if MEMP_MEM_MALLOC - -#include "mem.h" - -#define memp_init() -#define memp_malloc(type) mem_malloc(memp_sizes[type]) -#define memp_free(type, mem) mem_free(mem) - -#else /* MEMP_MEM_MALLOC */ - -#if MEM_USE_POOLS -/** This structure is used to save the pool one element came from. */ -struct memp_malloc_helper -{ - memp_t poolnr; -}; -#endif /* MEM_USE_POOLS */ - -void memp_init(void); - -#if MEMP_OVERFLOW_CHECK -void *memp_malloc_fn(memp_t type, const char* file, const int line); -#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__) -#else -void *memp_malloc(memp_t type); -#endif -void memp_free(memp_t type, void *mem); - -#endif /* MEMP_MEM_MALLOC */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_MEMP_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __LWIP_MEMP_H__ +#define __LWIP_MEMP_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */ +typedef enum { +#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name, +#include "lwip/memp_std.h" + MEMP_MAX +} memp_t; + +#if MEM_USE_POOLS +/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */ +typedef enum { + /* Get the first (via: + MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/ + MEMP_POOL_HELPER_FIRST = ((u8_t) +#define LWIP_MEMPOOL(name,num,size,desc) +#define LWIP_MALLOC_MEMPOOL_START 1 +#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0 +#define LWIP_MALLOC_MEMPOOL_END +#include "lwip/memp_std.h" + ) , + /* Get the last (via: + MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */ + MEMP_POOL_HELPER_LAST = ((u8_t) +#define LWIP_MEMPOOL(name,num,size,desc) +#define LWIP_MALLOC_MEMPOOL_START +#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size * +#define LWIP_MALLOC_MEMPOOL_END 1 +#include "lwip/memp_std.h" + ) +} memp_pool_helper_t; + +/* The actual start and stop values are here (cast them over) + We use this helper type and these defines so we can avoid using const memp_t values */ +#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST) +#define MEMP_POOL_LAST ((memp_t) MEMP_POOL_HELPER_LAST) +#endif /* MEM_USE_POOLS */ + +#if MEMP_MEM_MALLOC || MEM_USE_POOLS +extern const u32_t memp_sizes[MEMP_MAX]; +#endif /* MEMP_MEM_MALLOC || MEM_USE_POOLS */ + +#if MEMP_MEM_MALLOC + +#include "mem.h" + +#define memp_init() +#define memp_malloc(type) mem_malloc(memp_sizes[type]) +#define memp_free(type, mem) mem_free(mem) + +#else /* MEMP_MEM_MALLOC */ + +#if MEM_USE_POOLS +/** This structure is used to save the pool one element came from. */ +struct memp_malloc_helper +{ + memp_t poolnr; +}; +#endif /* MEM_USE_POOLS */ + +void memp_init(void); + +#if MEMP_OVERFLOW_CHECK +void *memp_malloc_fn(memp_t type, const char* file, const int line); +#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__) +#else +void *memp_malloc(memp_t type); +#endif +void memp_free(memp_t type, void *mem); + +#endif /* MEMP_MEM_MALLOC */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_MEMP_H__ */ diff --git a/include/lwip/lwip/memp_std.h b/include/lwip/lwip/memp_std.h index ea1108bd..592a2824 100644 --- a/include/lwip/lwip/memp_std.h +++ b/include/lwip/lwip/memp_std.h @@ -1,135 +1,135 @@ -/* - * SETUP: Make sure we define everything we will need. - * - * We have create three types of pools: - * 1) MEMPOOL - standard pools - * 2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c - * 3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct - * - * If the include'r doesn't require any special treatment of each of the types - * above, then will declare #2 & #3 to be just standard mempools. - */ -#ifndef LWIP_MALLOC_MEMPOOL -/* This treats "malloc pools" just like any other pool. - The pools are a little bigger to provide 'size' as the amount of user data. */ -#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + sizeof(struct memp_malloc_helper)), "MALLOC_"#size) -#define LWIP_MALLOC_MEMPOOL_START -#define LWIP_MALLOC_MEMPOOL_END -#endif /* LWIP_MALLOC_MEMPOOL */ - -#ifndef LWIP_PBUF_MEMPOOL -/* This treats "pbuf pools" just like any other pool. - * Allocates buffers for a pbuf struct AND a payload size */ -#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc) -#endif /* LWIP_PBUF_MEMPOOL */ - - -/* - * A list of internal pools used by LWIP. - * - * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description) - * creates a pool name MEMP_pool_name. description is used in stats.c - */ -#if LWIP_RAW -LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") -#endif /* LWIP_RAW */ - -#if LWIP_UDP -LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") -#endif /* LWIP_UDP */ - -#if LWIP_TCP -LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") -LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") -LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") -#endif /* LWIP_TCP */ - -#if IP_REASSEMBLY -LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") -#endif /* IP_REASSEMBLY */ -#if (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) || LWIP_IPV6_FRAG -LWIP_MEMPOOL(FRAG_PBUF, MEMP_NUM_FRAG_PBUF, sizeof(struct pbuf_custom_ref),"FRAG_PBUF") -#endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ - -#if LWIP_NETCONN -LWIP_MEMPOOL(NETBUF, MEMP_NUM_NETBUF, sizeof(struct netbuf), "NETBUF") -LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), "NETCONN") -#endif /* LWIP_NETCONN */ - -#if NO_SYS==0 -LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API") -#if !LWIP_TCPIP_CORE_LOCKING_INPUT -LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT") -#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ -#endif /* NO_SYS==0 */ - -#if LWIP_ARP && ARP_QUEUEING -LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE") -#endif /* LWIP_ARP && ARP_QUEUEING */ - -#if LWIP_IGMP -LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP") -#endif /* LWIP_IGMP */ - -#if (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) /* LWIP_TIMERS */ -LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT") -#endif /* LWIP_TIMERS */ - -#if LWIP_SNMP -LWIP_MEMPOOL(SNMP_ROOTNODE, MEMP_NUM_SNMP_ROOTNODE, sizeof(struct mib_list_rootnode), "SNMP_ROOTNODE") -LWIP_MEMPOOL(SNMP_NODE, MEMP_NUM_SNMP_NODE, sizeof(struct mib_list_node), "SNMP_NODE") -LWIP_MEMPOOL(SNMP_VARBIND, MEMP_NUM_SNMP_VARBIND, sizeof(struct snmp_varbind), "SNMP_VARBIND") -LWIP_MEMPOOL(SNMP_VALUE, MEMP_NUM_SNMP_VALUE, SNMP_MAX_VALUE_SIZE, "SNMP_VALUE") -#endif /* LWIP_SNMP */ -#if LWIP_DNS && LWIP_SOCKET -LWIP_MEMPOOL(NETDB, MEMP_NUM_NETDB, NETDB_ELEM_SIZE, "NETDB") -#endif /* LWIP_DNS && LWIP_SOCKET */ -#if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC -LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE, "LOCALHOSTLIST") -#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ -#if PPP_SUPPORT && PPPOE_SUPPORT -LWIP_MEMPOOL(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") -#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ - -#if LWIP_IPV6 && LWIP_ND6_QUEUEING -LWIP_MEMPOOL(ND6_QUEUE, MEMP_NUM_ND6_QUEUE, sizeof(struct nd6_q_entry), "ND6_QUEUE") -#endif /* LWIP_IPV6 && LWIP_ND6_QUEUEING */ - -#if LWIP_IPV6 && LWIP_IPV6_REASS -LWIP_MEMPOOL(IP6_REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip6_reassdata), "IP6_REASSDATA") -#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_MLD -LWIP_MEMPOOL(MLD6_GROUP, MEMP_NUM_MLD6_GROUP, sizeof(struct mld_group), "MLD6_GROUP") -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - - -/* - * A list of pools of pbuf's used by LWIP. - * - * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description) - * creates a pool name MEMP_pool_name. description is used in stats.c - * This allocates enough space for the pbuf struct and a payload. - * (Example: pbuf_payload_size=0 allocates only size for the struct) - */ -LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM") -LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL") - - -/* - * Allow for user-defined pools; this must be explicitly set in lwipopts.h - * since the default is to NOT look for lwippools.h - */ -#if MEMP_USE_CUSTOM_POOLS -#include "lwippools.h" -#endif /* MEMP_USE_CUSTOM_POOLS */ - -/* - * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later - * (#undef is ignored for something that is not defined) - */ -#undef LWIP_MEMPOOL -#undef LWIP_MALLOC_MEMPOOL -#undef LWIP_MALLOC_MEMPOOL_START -#undef LWIP_MALLOC_MEMPOOL_END -#undef LWIP_PBUF_MEMPOOL +/* + * SETUP: Make sure we define everything we will need. + * + * We have create three types of pools: + * 1) MEMPOOL - standard pools + * 2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c + * 3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct + * + * If the include'r doesn't require any special treatment of each of the types + * above, then will declare #2 & #3 to be just standard mempools. + */ +#ifndef LWIP_MALLOC_MEMPOOL +/* This treats "malloc pools" just like any other pool. + The pools are a little bigger to provide 'size' as the amount of user data. */ +#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + sizeof(struct memp_malloc_helper)), "MALLOC_"#size) +#define LWIP_MALLOC_MEMPOOL_START +#define LWIP_MALLOC_MEMPOOL_END +#endif /* LWIP_MALLOC_MEMPOOL */ + +#ifndef LWIP_PBUF_MEMPOOL +/* This treats "pbuf pools" just like any other pool. + * Allocates buffers for a pbuf struct AND a payload size */ +#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc) +#endif /* LWIP_PBUF_MEMPOOL */ + + +/* + * A list of internal pools used by LWIP. + * + * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description) + * creates a pool name MEMP_pool_name. description is used in stats.c + */ +#if LWIP_RAW +LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") +#endif /* LWIP_RAW */ + +#if LWIP_UDP +LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") +#endif /* LWIP_UDP */ + +#if LWIP_TCP +LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") +LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") +LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") +#endif /* LWIP_TCP */ + +#if IP_REASSEMBLY +LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") +#endif /* IP_REASSEMBLY */ +#if (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) || LWIP_IPV6_FRAG +LWIP_MEMPOOL(FRAG_PBUF, MEMP_NUM_FRAG_PBUF, sizeof(struct pbuf_custom_ref),"FRAG_PBUF") +#endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ + +#if LWIP_NETCONN +LWIP_MEMPOOL(NETBUF, MEMP_NUM_NETBUF, sizeof(struct netbuf), "NETBUF") +LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), "NETCONN") +#endif /* LWIP_NETCONN */ + +#if NO_SYS==0 +LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API") +#if !LWIP_TCPIP_CORE_LOCKING_INPUT +LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT") +#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ +#endif /* NO_SYS==0 */ + +#if LWIP_ARP && ARP_QUEUEING +LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE") +#endif /* LWIP_ARP && ARP_QUEUEING */ + +#if LWIP_IGMP +LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP") +#endif /* LWIP_IGMP */ + +#if (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) /* LWIP_TIMERS */ +LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT") +#endif /* LWIP_TIMERS */ + +#if LWIP_SNMP +LWIP_MEMPOOL(SNMP_ROOTNODE, MEMP_NUM_SNMP_ROOTNODE, sizeof(struct mib_list_rootnode), "SNMP_ROOTNODE") +LWIP_MEMPOOL(SNMP_NODE, MEMP_NUM_SNMP_NODE, sizeof(struct mib_list_node), "SNMP_NODE") +LWIP_MEMPOOL(SNMP_VARBIND, MEMP_NUM_SNMP_VARBIND, sizeof(struct snmp_varbind), "SNMP_VARBIND") +LWIP_MEMPOOL(SNMP_VALUE, MEMP_NUM_SNMP_VALUE, SNMP_MAX_VALUE_SIZE, "SNMP_VALUE") +#endif /* LWIP_SNMP */ +#if LWIP_DNS && LWIP_SOCKET +LWIP_MEMPOOL(NETDB, MEMP_NUM_NETDB, NETDB_ELEM_SIZE, "NETDB") +#endif /* LWIP_DNS && LWIP_SOCKET */ +#if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC +LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE, "LOCALHOSTLIST") +#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ +#if PPP_SUPPORT && PPPOE_SUPPORT +LWIP_MEMPOOL(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") +#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ + +#if LWIP_IPV6 && LWIP_ND6_QUEUEING +LWIP_MEMPOOL(ND6_QUEUE, MEMP_NUM_ND6_QUEUE, sizeof(struct nd6_q_entry), "ND6_QUEUE") +#endif /* LWIP_IPV6 && LWIP_ND6_QUEUEING */ + +#if LWIP_IPV6 && LWIP_IPV6_REASS +LWIP_MEMPOOL(IP6_REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip6_reassdata), "IP6_REASSDATA") +#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ + +#if LWIP_IPV6 && LWIP_IPV6_MLD +LWIP_MEMPOOL(MLD6_GROUP, MEMP_NUM_MLD6_GROUP, sizeof(struct mld_group), "MLD6_GROUP") +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + + +/* + * A list of pools of pbuf's used by LWIP. + * + * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description) + * creates a pool name MEMP_pool_name. description is used in stats.c + * This allocates enough space for the pbuf struct and a payload. + * (Example: pbuf_payload_size=0 allocates only size for the struct) + */ +LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM") +LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL") + + +/* + * Allow for user-defined pools; this must be explicitly set in lwipopts.h + * since the default is to NOT look for lwippools.h + */ +#if MEMP_USE_CUSTOM_POOLS +#include "lwippools.h" +#endif /* MEMP_USE_CUSTOM_POOLS */ + +/* + * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later + * (#undef is ignored for something that is not defined) + */ +#undef LWIP_MEMPOOL +#undef LWIP_MALLOC_MEMPOOL +#undef LWIP_MALLOC_MEMPOOL_START +#undef LWIP_MALLOC_MEMPOOL_END +#undef LWIP_PBUF_MEMPOOL diff --git a/include/lwip/lwip/netbuf.h b/include/lwip/lwip/netbuf.h index c086d81d..d12fe270 100644 --- a/include/lwip/lwip/netbuf.h +++ b/include/lwip/lwip/netbuf.h @@ -1,112 +1,112 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_NETBUF_H__ -#define __LWIP_NETBUF_H__ - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** This netbuf has dest-addr/port set */ -#define NETBUF_FLAG_DESTADDR 0x01 -/** This netbuf includes a checksum */ -#define NETBUF_FLAG_CHKSUM 0x02 - -struct netbuf { - struct pbuf *p, *ptr; - ipX_addr_t addr; - u16_t port; -#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY -#if LWIP_CHECKSUM_ON_COPY - u8_t flags; -#endif /* LWIP_CHECKSUM_ON_COPY */ - u16_t toport_chksum; -#if LWIP_NETBUF_RECVINFO - ipX_addr_t toaddr; -#endif /* LWIP_NETBUF_RECVINFO */ -#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ -}; - -/* Network buffer functions: */ -struct netbuf * netbuf_new (void); -void netbuf_delete (struct netbuf *buf); -void * netbuf_alloc (struct netbuf *buf, u16_t size); -void netbuf_free (struct netbuf *buf); -err_t netbuf_ref (struct netbuf *buf, - const void *dataptr, u16_t size); -void netbuf_chain (struct netbuf *head, - struct netbuf *tail); - -err_t netbuf_data (struct netbuf *buf, - void **dataptr, u16_t *len); -s8_t netbuf_next (struct netbuf *buf); -void netbuf_first (struct netbuf *buf); - - -#define netbuf_copy_partial(buf, dataptr, len, offset) \ - pbuf_copy_partial((buf)->p, (dataptr), (len), (offset)) -#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) -#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len) -#define netbuf_len(buf) ((buf)->p->tot_len) -#define netbuf_fromaddr(buf) (ipX_2_ip(&((buf)->addr))) -#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set(ipX_2_ip(&((buf)->addr)), fromaddr) -#define netbuf_fromport(buf) ((buf)->port) -#if LWIP_NETBUF_RECVINFO -#define netbuf_destaddr(buf) (ipX_2_ip(&((buf)->toaddr))) -#define netbuf_set_destaddr(buf, destaddr) ip_addr_set(ipX_2_ip(&((buf)->toaddr)), destaddr) -#define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) -#endif /* LWIP_NETBUF_RECVINFO */ -#if LWIP_CHECKSUM_ON_COPY -#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \ - (buf)->toport_chksum = chksum; } while(0) -#endif /* LWIP_CHECKSUM_ON_COPY */ - -#if LWIP_IPV6 -#define netbuf_fromaddr_ip6(buf) (ipX_2_ip6(&((buf)->addr))) -#define netbuf_set_fromaddr_ip6(buf, fromaddr) ip6_addr_set(ipX_2_ip6(&((buf)->addr)), fromaddr) -#define netbuf_destaddr_ip6(buf) (ipX_2_ip6(&((buf)->toaddr))) -#define netbuf_set_destaddr_ip6(buf, destaddr) ip6_addr_set(ipX_2_ip6(&((buf)->toaddr)), destaddr) -#endif /* LWIP_IPV6 */ - -#define netbuf_fromaddr_ipX(buf) (&((buf)->addr)) -#define netbuf_destaddr_ipX(buf) (&((buf)->toaddr)) - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_NETBUF_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_NETBUF_H__ +#define __LWIP_NETBUF_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** This netbuf has dest-addr/port set */ +#define NETBUF_FLAG_DESTADDR 0x01 +/** This netbuf includes a checksum */ +#define NETBUF_FLAG_CHKSUM 0x02 + +struct netbuf { + struct pbuf *p, *ptr; + ipX_addr_t addr; + u16_t port; +#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY +#if LWIP_CHECKSUM_ON_COPY + u8_t flags; +#endif /* LWIP_CHECKSUM_ON_COPY */ + u16_t toport_chksum; +#if LWIP_NETBUF_RECVINFO + ipX_addr_t toaddr; +#endif /* LWIP_NETBUF_RECVINFO */ +#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ +}; + +/* Network buffer functions: */ +struct netbuf * netbuf_new (void); +void netbuf_delete (struct netbuf *buf); +void * netbuf_alloc (struct netbuf *buf, u16_t size); +void netbuf_free (struct netbuf *buf); +err_t netbuf_ref (struct netbuf *buf, + const void *dataptr, u16_t size); +void netbuf_chain (struct netbuf *head, + struct netbuf *tail); + +err_t netbuf_data (struct netbuf *buf, + void **dataptr, u16_t *len); +s8_t netbuf_next (struct netbuf *buf); +void netbuf_first (struct netbuf *buf); + + +#define netbuf_copy_partial(buf, dataptr, len, offset) \ + pbuf_copy_partial((buf)->p, (dataptr), (len), (offset)) +#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) +#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len) +#define netbuf_len(buf) ((buf)->p->tot_len) +#define netbuf_fromaddr(buf) (ipX_2_ip(&((buf)->addr))) +#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set(ipX_2_ip(&((buf)->addr)), fromaddr) +#define netbuf_fromport(buf) ((buf)->port) +#if LWIP_NETBUF_RECVINFO +#define netbuf_destaddr(buf) (ipX_2_ip(&((buf)->toaddr))) +#define netbuf_set_destaddr(buf, destaddr) ip_addr_set(ipX_2_ip(&((buf)->toaddr)), destaddr) +#define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) +#endif /* LWIP_NETBUF_RECVINFO */ +#if LWIP_CHECKSUM_ON_COPY +#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \ + (buf)->toport_chksum = chksum; } while(0) +#endif /* LWIP_CHECKSUM_ON_COPY */ + +#if LWIP_IPV6 +#define netbuf_fromaddr_ip6(buf) (ipX_2_ip6(&((buf)->addr))) +#define netbuf_set_fromaddr_ip6(buf, fromaddr) ip6_addr_set(ipX_2_ip6(&((buf)->addr)), fromaddr) +#define netbuf_destaddr_ip6(buf) (ipX_2_ip6(&((buf)->toaddr))) +#define netbuf_set_destaddr_ip6(buf, destaddr) ip6_addr_set(ipX_2_ip6(&((buf)->toaddr)), destaddr) +#endif /* LWIP_IPV6 */ + +#define netbuf_fromaddr_ipX(buf) (&((buf)->addr)) +#define netbuf_destaddr_ipX(buf) (&((buf)->toaddr)) + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_NETBUF_H__ */ diff --git a/include/lwip/lwip/netdb.h b/include/lwip/lwip/netdb.h index 4b7c07a6..7587e2f2 100644 --- a/include/lwip/lwip/netdb.h +++ b/include/lwip/lwip/netdb.h @@ -1,124 +1,124 @@ -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef __LWIP_NETDB_H__ -#define __LWIP_NETDB_H__ - -#include "lwip/opt.h" - -#if LWIP_DNS && LWIP_SOCKET - -#include /* for size_t */ - -#include "lwip/inet.h" -#include "lwip/sockets.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* some rarely used options */ -#ifndef LWIP_DNS_API_DECLARE_H_ERRNO -#define LWIP_DNS_API_DECLARE_H_ERRNO 1 -#endif - -#ifndef LWIP_DNS_API_DEFINE_ERRORS -#define LWIP_DNS_API_DEFINE_ERRORS 1 -#endif - -#ifndef LWIP_DNS_API_DECLARE_STRUCTS -#define LWIP_DNS_API_DECLARE_STRUCTS 1 -#endif - -#if LWIP_DNS_API_DEFINE_ERRORS -/** Errors used by the DNS API functions, h_errno can be one of them */ -#define EAI_NONAME 200 -#define EAI_SERVICE 201 -#define EAI_FAIL 202 -#define EAI_MEMORY 203 - -#define HOST_NOT_FOUND 210 -#define NO_DATA 211 -#define NO_RECOVERY 212 -#define TRY_AGAIN 213 -#endif /* LWIP_DNS_API_DEFINE_ERRORS */ - -#if LWIP_DNS_API_DECLARE_STRUCTS -struct hostent { - char *h_name; /* Official name of the host. */ - char **h_aliases; /* A pointer to an array of pointers to alternative host names, - terminated by a null pointer. */ - int h_addrtype; /* Address type. */ - int h_length; /* The length, in bytes, of the address. */ - char **h_addr_list; /* A pointer to an array of pointers to network addresses (in - network byte order) for the host, terminated by a null pointer. */ -#define h_addr h_addr_list[0] /* for backward compatibility */ -}; - -struct addrinfo { - int ai_flags; /* Input flags. */ - int ai_family; /* Address family of socket. */ - int ai_socktype; /* Socket type. */ - int ai_protocol; /* Protocol of socket. */ - socklen_t ai_addrlen; /* Length of socket address. */ - struct sockaddr *ai_addr; /* Socket address of socket. */ - char *ai_canonname; /* Canonical name of service location. */ - struct addrinfo *ai_next; /* Pointer to next in list. */ -}; -#endif /* LWIP_DNS_API_DECLARE_STRUCTS */ - -#if LWIP_DNS_API_DECLARE_H_ERRNO -/* application accessable error code set by the DNS API functions */ -extern int h_errno; -#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/ - -struct hostent *lwip_gethostbyname(const char *name); -int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, - size_t buflen, struct hostent **result, int *h_errnop); -void lwip_freeaddrinfo(struct addrinfo *ai); -int lwip_getaddrinfo(const char *nodename, - const char *servname, - const struct addrinfo *hints, - struct addrinfo **res); - -#if LWIP_COMPAT_SOCKETS -#define gethostbyname(name) lwip_gethostbyname(name) -#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \ - lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop) -#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo) -#define getaddrinfo(nodname, servname, hints, res) \ - lwip_getaddrinfo(nodname, servname, hints, res) -#endif /* LWIP_COMPAT_SOCKETS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DNS && LWIP_SOCKET */ - -#endif /* __LWIP_NETDB_H__ */ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef __LWIP_NETDB_H__ +#define __LWIP_NETDB_H__ + +#include "lwip/opt.h" + +#if LWIP_DNS && LWIP_SOCKET + +#include /* for size_t */ + +#include "lwip/inet.h" +#include "lwip/sockets.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* some rarely used options */ +#ifndef LWIP_DNS_API_DECLARE_H_ERRNO +#define LWIP_DNS_API_DECLARE_H_ERRNO 1 +#endif + +#ifndef LWIP_DNS_API_DEFINE_ERRORS +#define LWIP_DNS_API_DEFINE_ERRORS 1 +#endif + +#ifndef LWIP_DNS_API_DECLARE_STRUCTS +#define LWIP_DNS_API_DECLARE_STRUCTS 1 +#endif + +#if LWIP_DNS_API_DEFINE_ERRORS +/** Errors used by the DNS API functions, h_errno can be one of them */ +#define EAI_NONAME 200 +#define EAI_SERVICE 201 +#define EAI_FAIL 202 +#define EAI_MEMORY 203 + +#define HOST_NOT_FOUND 210 +#define NO_DATA 211 +#define NO_RECOVERY 212 +#define TRY_AGAIN 213 +#endif /* LWIP_DNS_API_DEFINE_ERRORS */ + +#if LWIP_DNS_API_DECLARE_STRUCTS +struct hostent { + char *h_name; /* Official name of the host. */ + char **h_aliases; /* A pointer to an array of pointers to alternative host names, + terminated by a null pointer. */ + int h_addrtype; /* Address type. */ + int h_length; /* The length, in bytes, of the address. */ + char **h_addr_list; /* A pointer to an array of pointers to network addresses (in + network byte order) for the host, terminated by a null pointer. */ +#define h_addr h_addr_list[0] /* for backward compatibility */ +}; + +struct addrinfo { + int ai_flags; /* Input flags. */ + int ai_family; /* Address family of socket. */ + int ai_socktype; /* Socket type. */ + int ai_protocol; /* Protocol of socket. */ + socklen_t ai_addrlen; /* Length of socket address. */ + struct sockaddr *ai_addr; /* Socket address of socket. */ + char *ai_canonname; /* Canonical name of service location. */ + struct addrinfo *ai_next; /* Pointer to next in list. */ +}; +#endif /* LWIP_DNS_API_DECLARE_STRUCTS */ + +#if LWIP_DNS_API_DECLARE_H_ERRNO +/* application accessable error code set by the DNS API functions */ +extern int h_errno; +#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/ + +struct hostent *lwip_gethostbyname(const char *name); +int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop); +void lwip_freeaddrinfo(struct addrinfo *ai); +int lwip_getaddrinfo(const char *nodename, + const char *servname, + const struct addrinfo *hints, + struct addrinfo **res); + +#if LWIP_COMPAT_SOCKETS +#define gethostbyname(name) lwip_gethostbyname(name) +#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \ + lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop) +#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo) +#define getaddrinfo(nodname, servname, hints, res) \ + lwip_getaddrinfo(nodname, servname, hints, res) +#endif /* LWIP_COMPAT_SOCKETS */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DNS && LWIP_SOCKET */ + +#endif /* __LWIP_NETDB_H__ */ diff --git a/include/lwip/lwip/netif.h b/include/lwip/lwip/netif.h index 49084b35..ef7b92b5 100644 --- a/include/lwip/lwip/netif.h +++ b/include/lwip/lwip/netif.h @@ -1,393 +1,393 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_NETIF_H__ -#define __LWIP_NETIF_H__ - -#include "lwip/opt.h" - -#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) - -#include "lwip/err.h" - -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#if LWIP_DHCP -struct dhcp; -#endif -#if LWIP_AUTOIP -struct autoip; -#endif -#if LWIP_IPV6_DHCP6 -#include "lwip/dhcp6.h" -#endif /* LWIP_IPV6_DHCP6 */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Throughout this file, IP addresses are expected to be in - * the same byte order as in IP_PCB. */ - -/** must be the maximum of all used hardware address lengths - across all types of interfaces in use */ -#define NETIF_MAX_HWADDR_LEN 6U - -/** Whether the network interface is 'up'. This is - * a software flag used to control whether this network - * interface is enabled and processes traffic. - * It is set by the startup code (for static IP configuration) or - * by dhcp/autoip when an address has been assigned. - */ -#define NETIF_FLAG_UP 0x01U -/** If set, the netif has broadcast capability. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_BROADCAST 0x02U -/** If set, the netif is one end of a point-to-point connection. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_POINTTOPOINT 0x04U -/** If set, the interface is configured using DHCP. - * Set by the DHCP code when starting or stopping DHCP. */ -#define NETIF_FLAG_DHCP 0x08U -/** If set, the interface has an active link - * (set by the network interface driver). - * Either set by the netif driver in its init function (if the link - * is up at that time) or at a later point once the link comes up - * (if link detection is supported by the hardware). */ -#define NETIF_FLAG_LINK_UP 0x10U -/** If set, the netif is an ethernet device using ARP. - * Set by the netif driver in its init function. - * Used to check input packet types and use of DHCP. */ -#define NETIF_FLAG_ETHARP 0x20U -/** If set, the netif is an ethernet device. It might not use - * ARP or TCP/IP if it is used for PPPoE only. - */ -#define NETIF_FLAG_ETHERNET 0x40U -/** If set, the netif has IGMP capability. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_IGMP 0x80U - -/** Function prototype for netif init functions. Set up flags and output/linkoutput - * callback functions in this function. - * - * @param netif The netif to initialize - */ -typedef err_t (*netif_init_fn)(struct netif *netif); -/** Function prototype for netif->input functions. This function is saved as 'input' - * callback function in the netif struct. Call it when a packet has been received. - * - * @param p The received packet, copied into a pbuf - * @param inp The netif which received the packet - */ -typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp); -/** Function prototype for netif->output functions. Called by lwIP when a packet - * shall be sent. For ethernet netif, set this to 'etharp_output' and set - * 'linkoutput'. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (p->payload points to IP header) - * @param ipaddr The IP address to which the packet shall be sent - */ -typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p, - ip_addr_t *ipaddr); -#if LWIP_IPV6 -/** Function prototype for netif->output_ip6 functions. Called by lwIP when a packet - * shall be sent. For ethernet netif, set this to 'nd_output' and set - * 'linkoutput'. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (p->payload points to IP header) - * @param ipaddr The IPv6 address to which the packet shall be sent - */ -typedef err_t (*netif_output_ip6_fn)(struct netif *netif, struct pbuf *p, - ip6_addr_t *ipaddr); -#endif /* LWIP_IPV6 */ -/** Function prototype for netif->linkoutput functions. Only used for ethernet - * netifs. This function is called by ARP when a packet shall be sent. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (raw ethernet packet) - */ -typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p); -/** Function prototype for netif status- or link-callback functions. */ -typedef void (*netif_status_callback_fn)(struct netif *netif); -/** Function prototype for netif igmp_mac_filter functions */ -typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, - ip_addr_t *group, u8_t action); -#if LWIP_IPV6 && LWIP_IPV6_MLD -/** Function prototype for netif mld_mac_filter functions */ -typedef err_t (*netif_mld_mac_filter_fn)(struct netif *netif, - ip6_addr_t *group, u8_t action); -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ -/*add DHCP event processing by LiuHan*/ -typedef void (*dhcp_event_fn)(void); - -/** Generic data structure used for all lwIP network interfaces. - * The following fields should be filled in by the initialization - * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ -struct netif { - /** pointer to next in linked list */ - struct netif *next; - - /** IP address configuration in network byte order */ - ip_addr_t ip_addr; - ip_addr_t netmask; - ip_addr_t gw; - - ipX_addr_t link_local_addr; - -#if LWIP_IPV6 - /** Array of IPv6 addresses for this netif. */ - ip6_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES]; - /** The state of each IPv6 address (Tentative, Preferred, etc). - * @see ip6_addr.h */ - u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES]; -#endif /* LWIP_IPV6 */ - /** This function is called by the network device driver - * to pass a packet up the TCP/IP stack. */ - netif_input_fn input; - /** This function is called by the IP module when it wants - * to send a packet on the interface. This function typically - * first resolves the hardware address, then sends the packet. */ - netif_output_fn output; - /** This function is called by the ARP module when it wants - * to send a packet on the interface. This function outputs - * the pbuf as-is on the link medium. */ - netif_linkoutput_fn linkoutput; -#if LWIP_IPV6 - /** This function is called by the IPv6 module when it wants - * to send a packet on the interface. This function typically - * first resolves the hardware address, then sends the packet. */ - netif_output_ip6_fn output_ip6; -#endif /* LWIP_IPV6 */ -#if LWIP_NETIF_STATUS_CALLBACK - /** This function is called when the netif state is set to up or down - */ - netif_status_callback_fn status_callback; -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_LINK_CALLBACK - /** This function is called when the netif link is set to up or down - */ - netif_status_callback_fn link_callback; -#endif /* LWIP_NETIF_LINK_CALLBACK */ -#if LWIP_NETIF_REMOVE_CALLBACK - /** This function is called when the netif has been removed */ - netif_status_callback_fn remove_callback; -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - /** This field can be set by the device driver and could point - * to state information for the device. */ - void *state; -#if LWIP_DHCP - /** the DHCP client state information for this netif */ - struct dhcp *dhcp; - struct udp_pcb *dhcps_pcb; //dhcps - dhcp_event_fn dhcp_event; -#endif /* LWIP_DHCP */ -#if LWIP_AUTOIP - /** the AutoIP client state information for this netif */ - struct autoip *autoip; -#endif -#if LWIP_IPV6_AUTOCONFIG - /** is this netif enabled for IPv6 autoconfiguration */ - u8_t ip6_autoconfig_enabled; -#endif /* LWIP_IPV6_AUTOCONFIG */ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /** Number of Router Solicitation messages that remain to be sent. */ - u8_t rs_count; -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ -#if LWIP_IPV6_DHCP6 - /** the DHCPv6 client state information for this netif */ - struct dhcp6 *dhcp6; -#endif /* LWIP_IPV6_DHCP6 */ -#if LWIP_NETIF_HOSTNAME - /* the hostname for this netif, NULL is a valid value */ - char* hostname; -#endif /* LWIP_NETIF_HOSTNAME */ - /** maximum transfer unit (in bytes) */ - u16_t mtu; - /** number of bytes used in hwaddr */ - u8_t hwaddr_len; - /** link level hardware address of this interface */ - u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; - /** flags (see NETIF_FLAG_ above) */ - u8_t flags; - /** descriptive abbreviation */ - char name[2]; - /** number of this interface */ - u8_t num; -#if LWIP_SNMP - /** link type (from "snmp_ifType" enum from snmp.h) */ - u8_t link_type; - /** (estimate) link speed */ - u32_t link_speed; - /** timestamp at last change made (up/down) */ - u32_t ts; - /** counters */ - u32_t ifinoctets; - u32_t ifinucastpkts; - u32_t ifinnucastpkts; - u32_t ifindiscards; - u32_t ifoutoctets; - u32_t ifoutucastpkts; - u32_t ifoutnucastpkts; - u32_t ifoutdiscards; -#endif /* LWIP_SNMP */ -#if LWIP_IGMP - /** This function could be called to add or delete an entry in the multicast - filter table of the ethernet MAC.*/ - netif_igmp_mac_filter_fn igmp_mac_filter; -#endif /* LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD - /** This function could be called to add or delete an entry in the IPv6 multicast - filter table of the ethernet MAC. */ - netif_mld_mac_filter_fn mld_mac_filter; -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ -#if LWIP_NETIF_HWADDRHINT - u8_t *addr_hint; -#endif /* LWIP_NETIF_HWADDRHINT */ -#if ENABLE_LOOPBACK - /* List of packets to be queued for ourselves. */ - struct pbuf *loop_first; - struct pbuf *loop_last; -#if LWIP_LOOPBACK_MAX_PBUFS - u16_t loop_cnt_current; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ -#endif /* ENABLE_LOOPBACK */ -}; - -#if LWIP_SNMP -#define NETIF_INIT_SNMP(netif, type, speed) \ - /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \ - (netif)->link_type = (type); \ - /* your link speed here (units: bits per second) */ \ - (netif)->link_speed = (speed); \ - (netif)->ts = 0; \ - (netif)->ifinoctets = 0; \ - (netif)->ifinucastpkts = 0; \ - (netif)->ifinnucastpkts = 0; \ - (netif)->ifindiscards = 0; \ - (netif)->ifoutoctets = 0; \ - (netif)->ifoutucastpkts = 0; \ - (netif)->ifoutnucastpkts = 0; \ - (netif)->ifoutdiscards = 0 -#else /* LWIP_SNMP */ -#define NETIF_INIT_SNMP(netif, type, speed) -#endif /* LWIP_SNMP */ - - -/** The list of network interfaces. */ -extern struct netif *netif_list; -/** The default network interface. */ -extern struct netif *netif_default; - -void netif_init(void); - -struct netif *netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, - ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input); - -void -netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, - ip_addr_t *gw); -void netif_remove(struct netif * netif); - -/* Returns a network interface given its name. The name is of the form - "et0", where the first two letters are the "name" field in the - netif structure, and the digit is in the num field in the same - structure. */ -struct netif *netif_find(char *name); - -void netif_set_default(struct netif *netif); - -void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr); -void netif_set_netmask(struct netif *netif, ip_addr_t *netmask); -void netif_set_gw(struct netif *netif, ip_addr_t *gw); - -void netif_set_up(struct netif *netif); -void netif_set_down(struct netif *netif); -/** Ask if an interface is up */ -#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0) - -#if LWIP_NETIF_STATUS_CALLBACK -void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback); -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_REMOVE_CALLBACK -void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback); -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - -void netif_set_link_up(struct netif *netif); -void netif_set_link_down(struct netif *netif); -/** Ask if a link is up */ -#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0) - -#if LWIP_NETIF_LINK_CALLBACK -void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback); -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#if LWIP_NETIF_HOSTNAME -#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0) -#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL) -#endif /* LWIP_NETIF_HOSTNAME */ - -#if LWIP_IGMP -#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0) -#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL) -#endif /* LWIP_IGMP */ - -#if ENABLE_LOOPBACK -err_t netif_loop_output(struct netif *netif, struct pbuf *p, ip_addr_t *dest_ip); -void netif_poll(struct netif *netif); -#if !LWIP_NETIF_LOOPBACK_MULTITHREADING -void netif_poll_all(void); -#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -#if LWIP_IPV6 -#define netif_ip6_addr(netif, i) (&((netif)->ip6_addr[(i)])) -#define netif_ip6_addr_state(netif, i) ((netif)->ip6_addr_state[(i)]) -#define netif_ip6_addr_set_state(netif, i, state) ((netif)->ip6_addr_state[(i)] = (state)) -s8_t netif_matches_ip6_addr(struct netif * netif, ip6_addr_t * ip6addr); -void netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit); -#endif /* LWIP_IPV6 */ - -#if LWIP_NETIF_HWADDRHINT -#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint)) -#else /* LWIP_NETIF_HWADDRHINT */ -#define NETIF_SET_HWADDRHINT(netif, hint) -#endif /* LWIP_NETIF_HWADDRHINT */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_NETIF_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_NETIF_H__ +#define __LWIP_NETIF_H__ + +#include "lwip/opt.h" + +#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) + +#include "lwip/err.h" + +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#if LWIP_DHCP +struct dhcp; +#endif +#if LWIP_AUTOIP +struct autoip; +#endif +#if LWIP_IPV6_DHCP6 +#include "lwip/dhcp6.h" +#endif /* LWIP_IPV6_DHCP6 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Throughout this file, IP addresses are expected to be in + * the same byte order as in IP_PCB. */ + +/** must be the maximum of all used hardware address lengths + across all types of interfaces in use */ +#define NETIF_MAX_HWADDR_LEN 6U + +/** Whether the network interface is 'up'. This is + * a software flag used to control whether this network + * interface is enabled and processes traffic. + * It is set by the startup code (for static IP configuration) or + * by dhcp/autoip when an address has been assigned. + */ +#define NETIF_FLAG_UP 0x01U +/** If set, the netif has broadcast capability. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_BROADCAST 0x02U +/** If set, the netif is one end of a point-to-point connection. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_POINTTOPOINT 0x04U +/** If set, the interface is configured using DHCP. + * Set by the DHCP code when starting or stopping DHCP. */ +#define NETIF_FLAG_DHCP 0x08U +/** If set, the interface has an active link + * (set by the network interface driver). + * Either set by the netif driver in its init function (if the link + * is up at that time) or at a later point once the link comes up + * (if link detection is supported by the hardware). */ +#define NETIF_FLAG_LINK_UP 0x10U +/** If set, the netif is an ethernet device using ARP. + * Set by the netif driver in its init function. + * Used to check input packet types and use of DHCP. */ +#define NETIF_FLAG_ETHARP 0x20U +/** If set, the netif is an ethernet device. It might not use + * ARP or TCP/IP if it is used for PPPoE only. + */ +#define NETIF_FLAG_ETHERNET 0x40U +/** If set, the netif has IGMP capability. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_IGMP 0x80U + +/** Function prototype for netif init functions. Set up flags and output/linkoutput + * callback functions in this function. + * + * @param netif The netif to initialize + */ +typedef err_t (*netif_init_fn)(struct netif *netif); +/** Function prototype for netif->input functions. This function is saved as 'input' + * callback function in the netif struct. Call it when a packet has been received. + * + * @param p The received packet, copied into a pbuf + * @param inp The netif which received the packet + */ +typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp); +/** Function prototype for netif->output functions. Called by lwIP when a packet + * shall be sent. For ethernet netif, set this to 'etharp_output' and set + * 'linkoutput'. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (p->payload points to IP header) + * @param ipaddr The IP address to which the packet shall be sent + */ +typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p, + ip_addr_t *ipaddr); +#if LWIP_IPV6 +/** Function prototype for netif->output_ip6 functions. Called by lwIP when a packet + * shall be sent. For ethernet netif, set this to 'nd_output' and set + * 'linkoutput'. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (p->payload points to IP header) + * @param ipaddr The IPv6 address to which the packet shall be sent + */ +typedef err_t (*netif_output_ip6_fn)(struct netif *netif, struct pbuf *p, + ip6_addr_t *ipaddr); +#endif /* LWIP_IPV6 */ +/** Function prototype for netif->linkoutput functions. Only used for ethernet + * netifs. This function is called by ARP when a packet shall be sent. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (raw ethernet packet) + */ +typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p); +/** Function prototype for netif status- or link-callback functions. */ +typedef void (*netif_status_callback_fn)(struct netif *netif); +/** Function prototype for netif igmp_mac_filter functions */ +typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, + ip_addr_t *group, u8_t action); +#if LWIP_IPV6 && LWIP_IPV6_MLD +/** Function prototype for netif mld_mac_filter functions */ +typedef err_t (*netif_mld_mac_filter_fn)(struct netif *netif, + ip6_addr_t *group, u8_t action); +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +/*add DHCP event processing by LiuHan*/ +typedef void (*dhcp_event_fn)(void); + +/** Generic data structure used for all lwIP network interfaces. + * The following fields should be filled in by the initialization + * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ +struct netif { + /** pointer to next in linked list */ + struct netif *next; + + /** IP address configuration in network byte order */ + ip_addr_t ip_addr; + ip_addr_t netmask; + ip_addr_t gw; + + ipX_addr_t link_local_addr; + +#if LWIP_IPV6 + /** Array of IPv6 addresses for this netif. */ + ip6_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES]; + /** The state of each IPv6 address (Tentative, Preferred, etc). + * @see ip6_addr.h */ + u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES]; +#endif /* LWIP_IPV6 */ + /** This function is called by the network device driver + * to pass a packet up the TCP/IP stack. */ + netif_input_fn input; + /** This function is called by the IP module when it wants + * to send a packet on the interface. This function typically + * first resolves the hardware address, then sends the packet. */ + netif_output_fn output; + /** This function is called by the ARP module when it wants + * to send a packet on the interface. This function outputs + * the pbuf as-is on the link medium. */ + netif_linkoutput_fn linkoutput; +#if LWIP_IPV6 + /** This function is called by the IPv6 module when it wants + * to send a packet on the interface. This function typically + * first resolves the hardware address, then sends the packet. */ + netif_output_ip6_fn output_ip6; +#endif /* LWIP_IPV6 */ +#if LWIP_NETIF_STATUS_CALLBACK + /** This function is called when the netif state is set to up or down + */ + netif_status_callback_fn status_callback; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + /** This function is called when the netif link is set to up or down + */ + netif_status_callback_fn link_callback; +#endif /* LWIP_NETIF_LINK_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK + /** This function is called when the netif has been removed */ + netif_status_callback_fn remove_callback; +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + /** This field can be set by the device driver and could point + * to state information for the device. */ + void *state; +#if LWIP_DHCP + /** the DHCP client state information for this netif */ + struct dhcp *dhcp; + struct udp_pcb *dhcps_pcb; //dhcps + dhcp_event_fn dhcp_event; +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + /** the AutoIP client state information for this netif */ + struct autoip *autoip; +#endif +#if LWIP_IPV6_AUTOCONFIG + /** is this netif enabled for IPv6 autoconfiguration */ + u8_t ip6_autoconfig_enabled; +#endif /* LWIP_IPV6_AUTOCONFIG */ +#if LWIP_IPV6_SEND_ROUTER_SOLICIT + /** Number of Router Solicitation messages that remain to be sent. */ + u8_t rs_count; +#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ +#if LWIP_IPV6_DHCP6 + /** the DHCPv6 client state information for this netif */ + struct dhcp6 *dhcp6; +#endif /* LWIP_IPV6_DHCP6 */ +#if LWIP_NETIF_HOSTNAME + /* the hostname for this netif, NULL is a valid value */ + char* hostname; +#endif /* LWIP_NETIF_HOSTNAME */ + /** maximum transfer unit (in bytes) */ + u16_t mtu; + /** number of bytes used in hwaddr */ + u8_t hwaddr_len; + /** link level hardware address of this interface */ + u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; + /** flags (see NETIF_FLAG_ above) */ + u8_t flags; + /** descriptive abbreviation */ + char name[2]; + /** number of this interface */ + u8_t num; +#if LWIP_SNMP + /** link type (from "snmp_ifType" enum from snmp.h) */ + u8_t link_type; + /** (estimate) link speed */ + u32_t link_speed; + /** timestamp at last change made (up/down) */ + u32_t ts; + /** counters */ + u32_t ifinoctets; + u32_t ifinucastpkts; + u32_t ifinnucastpkts; + u32_t ifindiscards; + u32_t ifoutoctets; + u32_t ifoutucastpkts; + u32_t ifoutnucastpkts; + u32_t ifoutdiscards; +#endif /* LWIP_SNMP */ +#if LWIP_IGMP + /** This function could be called to add or delete an entry in the multicast + filter table of the ethernet MAC.*/ + netif_igmp_mac_filter_fn igmp_mac_filter; +#endif /* LWIP_IGMP */ +#if LWIP_IPV6 && LWIP_IPV6_MLD + /** This function could be called to add or delete an entry in the IPv6 multicast + filter table of the ethernet MAC. */ + netif_mld_mac_filter_fn mld_mac_filter; +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +#if LWIP_NETIF_HWADDRHINT + u8_t *addr_hint; +#endif /* LWIP_NETIF_HWADDRHINT */ +#if ENABLE_LOOPBACK + /* List of packets to be queued for ourselves. */ + struct pbuf *loop_first; + struct pbuf *loop_last; +#if LWIP_LOOPBACK_MAX_PBUFS + u16_t loop_cnt_current; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ +#endif /* ENABLE_LOOPBACK */ +}; + +#if LWIP_SNMP +#define NETIF_INIT_SNMP(netif, type, speed) \ + /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \ + (netif)->link_type = (type); \ + /* your link speed here (units: bits per second) */ \ + (netif)->link_speed = (speed); \ + (netif)->ts = 0; \ + (netif)->ifinoctets = 0; \ + (netif)->ifinucastpkts = 0; \ + (netif)->ifinnucastpkts = 0; \ + (netif)->ifindiscards = 0; \ + (netif)->ifoutoctets = 0; \ + (netif)->ifoutucastpkts = 0; \ + (netif)->ifoutnucastpkts = 0; \ + (netif)->ifoutdiscards = 0 +#else /* LWIP_SNMP */ +#define NETIF_INIT_SNMP(netif, type, speed) +#endif /* LWIP_SNMP */ + + +/** The list of network interfaces. */ +extern struct netif *netif_list; +/** The default network interface. */ +extern struct netif *netif_default; + +void netif_init(void); + +struct netif *netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input); + +void +netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw); +void netif_remove(struct netif * netif); + +/* Returns a network interface given its name. The name is of the form + "et0", where the first two letters are the "name" field in the + netif structure, and the digit is in the num field in the same + structure. */ +struct netif *netif_find(char *name); + +void netif_set_default(struct netif *netif); + +void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr); +void netif_set_netmask(struct netif *netif, ip_addr_t *netmask); +void netif_set_gw(struct netif *netif, ip_addr_t *gw); + +void netif_set_up(struct netif *netif); +void netif_set_down(struct netif *netif); +/** Ask if an interface is up */ +#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0) + +#if LWIP_NETIF_STATUS_CALLBACK +void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK +void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback); +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + +void netif_set_link_up(struct netif *netif); +void netif_set_link_down(struct netif *netif); +/** Ask if a link is up */ +#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0) + +#if LWIP_NETIF_LINK_CALLBACK +void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#if LWIP_NETIF_HOSTNAME +#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0) +#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL) +#endif /* LWIP_NETIF_HOSTNAME */ + +#if LWIP_IGMP +#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0) +#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL) +#endif /* LWIP_IGMP */ + +#if ENABLE_LOOPBACK +err_t netif_loop_output(struct netif *netif, struct pbuf *p, ip_addr_t *dest_ip); +void netif_poll(struct netif *netif); +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +void netif_poll_all(void); +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#if LWIP_IPV6 +#define netif_ip6_addr(netif, i) (&((netif)->ip6_addr[(i)])) +#define netif_ip6_addr_state(netif, i) ((netif)->ip6_addr_state[(i)]) +#define netif_ip6_addr_set_state(netif, i, state) ((netif)->ip6_addr_state[(i)] = (state)) +s8_t netif_matches_ip6_addr(struct netif * netif, ip6_addr_t * ip6addr); +void netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit); +#endif /* LWIP_IPV6 */ + +#if LWIP_NETIF_HWADDRHINT +#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint)) +#else /* LWIP_NETIF_HWADDRHINT */ +#define NETIF_SET_HWADDRHINT(netif, hint) +#endif /* LWIP_NETIF_HWADDRHINT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_NETIF_H__ */ diff --git a/include/lwip/lwip/netifapi.h b/include/lwip/lwip/netifapi.h index 141ac14c..33318efa 100644 --- a/include/lwip/lwip/netifapi.h +++ b/include/lwip/lwip/netifapi.h @@ -1,108 +1,108 @@ -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#ifndef __LWIP_NETIFAPI_H__ -#define __LWIP_NETIFAPI_H__ - -#include "lwip/opt.h" - -#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sys.h" -#include "lwip/netif.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*netifapi_void_fn)(struct netif *netif); -typedef err_t (*netifapi_errt_fn)(struct netif *netif); - -struct netifapi_msg_msg { -#if !LWIP_TCPIP_CORE_LOCKING - sys_sem_t sem; -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - err_t err; - struct netif *netif; - union { - struct { - ip_addr_t *ipaddr; - ip_addr_t *netmask; - ip_addr_t *gw; - void *state; - netif_init_fn init; - netif_input_fn input; - } add; - struct { - netifapi_void_fn voidfunc; - netifapi_errt_fn errtfunc; - } common; - } msg; -}; - -struct netifapi_msg { - void (* function)(struct netifapi_msg_msg *msg); - struct netifapi_msg_msg msg; -}; - - -/* API for application */ -err_t netifapi_netif_add ( struct netif *netif, - ip_addr_t *ipaddr, - ip_addr_t *netmask, - ip_addr_t *gw, - void *state, - netif_init_fn init, - netif_input_fn input); - -err_t netifapi_netif_set_addr ( struct netif *netif, - ip_addr_t *ipaddr, - ip_addr_t *netmask, - ip_addr_t *gw ); - -err_t netifapi_netif_common ( struct netif *netif, - netifapi_void_fn voidfunc, - netifapi_errt_fn errtfunc); - -#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL) -#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL) -#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL) -#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL) -#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start) -#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL) -#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start) -#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETIF_API */ - -#endif /* __LWIP_NETIFAPI_H__ */ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#ifndef __LWIP_NETIFAPI_H__ +#define __LWIP_NETIFAPI_H__ + +#include "lwip/opt.h" + +#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/netif.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*netifapi_void_fn)(struct netif *netif); +typedef err_t (*netifapi_errt_fn)(struct netif *netif); + +struct netifapi_msg_msg { +#if !LWIP_TCPIP_CORE_LOCKING + sys_sem_t sem; +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + err_t err; + struct netif *netif; + union { + struct { + ip_addr_t *ipaddr; + ip_addr_t *netmask; + ip_addr_t *gw; + void *state; + netif_init_fn init; + netif_input_fn input; + } add; + struct { + netifapi_void_fn voidfunc; + netifapi_errt_fn errtfunc; + } common; + } msg; +}; + +struct netifapi_msg { + void (* function)(struct netifapi_msg_msg *msg); + struct netifapi_msg_msg msg; +}; + + +/* API for application */ +err_t netifapi_netif_add ( struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw, + void *state, + netif_init_fn init, + netif_input_fn input); + +err_t netifapi_netif_set_addr ( struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw ); + +err_t netifapi_netif_common ( struct netif *netif, + netifapi_void_fn voidfunc, + netifapi_errt_fn errtfunc); + +#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL) +#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL) +#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL) +#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL) +#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start) +#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL) +#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start) +#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETIF_API */ + +#endif /* __LWIP_NETIFAPI_H__ */ diff --git a/include/lwip/lwip/opt.h b/include/lwip/lwip/opt.h index c97e24e4..01bd9c20 100644 --- a/include/lwip/lwip/opt.h +++ b/include/lwip/lwip/opt.h @@ -1,2422 +1,2422 @@ -/** - * @file - * - * lwIP Options Configuration - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_OPT_H__ -#define __LWIP_OPT_H__ - -/* - * Include user defined options first. Anything not defined in these files - * will be set to standard values. Override anything you dont like! - */ -#include "lwipopts.h" -#include "lwip/debug.h" - -/* - ----------------------------------------------- - ---------- Platform specific locking ---------- - ----------------------------------------------- -*/ - -/** - * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain - * critical regions during buffer allocation, deallocation and memory - * allocation and deallocation. - */ -#ifndef SYS_LIGHTWEIGHT_PROT -#define SYS_LIGHTWEIGHT_PROT 0 -#endif - -/** - * NO_SYS==1: Provides VERY minimal functionality. Otherwise, - * use lwIP facilities. - */ -#ifndef NO_SYS -#define NO_SYS 0 -#endif - -/** - * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 - * Mainly for compatibility to old versions. - */ -#ifndef NO_SYS_NO_TIMERS -#define NO_SYS_NO_TIMERS 0 -#endif - -/** - * MEMCPY: override this if you have a faster implementation at hand than the - * one included in your C library - */ -#ifndef MEMCPY -#define MEMCPY(dst,src,len) memcpy(dst,src,len) -#endif - -/** - * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a - * call to memcpy() if the length is known at compile time and is small. - */ -#ifndef SMEMCPY -#define SMEMCPY(dst,src,len) memcpy(dst,src,len) -#endif - -/* - ------------------------------------ - ---------- Memory options ---------- - ------------------------------------ -*/ -/** - * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library - * instead of the lwip internal allocator. Can save code size if you - * already use it. - */ -#ifndef MEM_LIBC_MALLOC -#define MEM_LIBC_MALLOC 0 -#endif - -/** -* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. -* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution -* speed and usage from interrupts! -*/ -#ifndef MEMP_MEM_MALLOC -#define MEMP_MEM_MALLOC 0 -#endif - -/** - * MEM_ALIGNMENT: should be set to the alignment of the CPU - * 4 byte alignment -> #define MEM_ALIGNMENT 4 - * 2 byte alignment -> #define MEM_ALIGNMENT 2 - */ -#ifndef MEM_ALIGNMENT -#define MEM_ALIGNMENT 1 -#endif - -/** - * MEM_SIZE: the size of the heap memory. If the application will send - * a lot of data that needs to be copied, this should be set high. - */ -#ifndef MEM_SIZE -#define MEM_SIZE 1600 -#endif - -/** - * MEMP_SEPARATE_POOLS: if defined to 1, each pool is placed in its own array. - * This can be used to individually change the location of each pool. - * Default is one big array for all pools - */ -#ifndef MEMP_SEPARATE_POOLS -#define MEMP_SEPARATE_POOLS 0 -#endif - -/** - * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable - * amount of bytes before and after each memp element in every pool and fills - * it with a prominent default value. - * MEMP_OVERFLOW_CHECK == 0 no checking - * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed - * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time - * memp_malloc() or memp_free() is called (useful but slow!) - */ -#ifndef MEMP_OVERFLOW_CHECK -#define MEMP_OVERFLOW_CHECK 0 -#endif - -/** - * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make - * sure that there are no cycles in the linked lists. - */ -#ifndef MEMP_SANITY_CHECK -#define MEMP_SANITY_CHECK 0 -#endif - -/** - * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set - * of memory pools of various sizes. When mem_malloc is called, an element of - * the smallest pool that can provide the length needed is returned. - * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. - */ -#ifndef MEM_USE_POOLS -#define MEM_USE_POOLS 0 -#endif - -/** - * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next - * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more - * reliable. */ -#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL -#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 -#endif - -/** - * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h - * that defines additional pools beyond the "standard" ones required - * by lwIP. If you set this to 1, you must have lwippools.h in your - * inlude path somewhere. - */ -#ifndef MEMP_USE_CUSTOM_POOLS -#define MEMP_USE_CUSTOM_POOLS 0 -#endif - -/** - * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from - * interrupt context (or another context that doesn't allow waiting for a - * semaphore). - * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, - * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs - * with each loop so that mem_free can run. - * - * ATTENTION: As you can see from the above description, this leads to dis-/ - * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc - * can need longer. - * - * If you don't want that, at least for NO_SYS=0, you can still use the following - * functions to enqueue a deallocation call which then runs in the tcpip_thread - * context: - * - pbuf_free_callback(p); - * - mem_free_callback(m); - */ -#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT -#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 -#endif - -/* - ------------------------------------------------ - ---------- Internal Memory Pool Sizes ---------- - ------------------------------------------------ -*/ -/** - * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). - * If the application sends a lot of data out of ROM (or other static memory), - * this should be set high. - */ -#ifndef MEMP_NUM_PBUF -#define MEMP_NUM_PBUF 16 -#endif - -/** - * MEMP_NUM_RAW_PCB: Number of raw connection PCBs - * (requires the LWIP_RAW option) - */ -#ifndef MEMP_NUM_RAW_PCB -#define MEMP_NUM_RAW_PCB 4 -#endif - -/** - * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One - * per active UDP "connection". - * (requires the LWIP_UDP option) - */ -#ifndef MEMP_NUM_UDP_PCB -#define MEMP_NUM_UDP_PCB 4 -#endif - -/** - * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. - * (requires the LWIP_TCP option) - */ -#ifndef MEMP_NUM_TCP_PCB -#define MEMP_NUM_TCP_PCB 5 -#endif - -/** - * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. - * (requires the LWIP_TCP option) - */ -#ifndef MEMP_NUM_TCP_PCB_LISTEN -#define MEMP_NUM_TCP_PCB_LISTEN 8 -#endif - -/** - * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. - * (requires the LWIP_TCP option) - */ -#ifndef MEMP_NUM_TCP_SEG -#define MEMP_NUM_TCP_SEG 16 -#endif - -/** - * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for - * reassembly (whole packets, not fragments!) - */ -#ifndef MEMP_NUM_REASSDATA -#define MEMP_NUM_REASSDATA 5 -#endif - -/** - * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent - * (fragments, not whole packets!). - * This is only used with IP_FRAG_USES_STATIC_BUF==0 and - * LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 with DMA-enabled MACs - * where the packet is not yet sent when netif->output returns. - */ -#ifndef MEMP_NUM_FRAG_PBUF -#define MEMP_NUM_FRAG_PBUF 15 -#endif - -/** - * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing - * packets (pbufs) that are waiting for an ARP request (to resolve - * their destination address) to finish. - * (requires the ARP_QUEUEING option) - */ -#ifndef MEMP_NUM_ARP_QUEUE -#define MEMP_NUM_ARP_QUEUE 30 -#endif - -/** - * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces - * can be members et the same time (one per netif - allsystems group -, plus one - * per netif membership). - * (requires the LWIP_IGMP option) - */ -#ifndef MEMP_NUM_IGMP_GROUP -#define MEMP_NUM_IGMP_GROUP 8 -#endif - -/** - * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. - * (requires NO_SYS==0) - * The default number of timeouts is calculated here for all enabled modules. - * The formula expects settings to be either '0' or '1'. - */ -#ifndef MEMP_NUM_SYS_TIMEOUT -#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) -#endif - -/** - * MEMP_NUM_NETBUF: the number of struct netbufs. - * (only needed if you use the sequential API, like api_lib.c) - */ -#ifndef MEMP_NUM_NETBUF -#define MEMP_NUM_NETBUF 2 -#endif - -/** - * MEMP_NUM_NETCONN: the number of struct netconns. - * (only needed if you use the sequential API, like api_lib.c) - */ -#ifndef MEMP_NUM_NETCONN -#define MEMP_NUM_NETCONN 4 -#endif - -/** - * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used - * for callback/timeout API communication. - * (only needed if you use tcpip.c) - */ -#ifndef MEMP_NUM_TCPIP_MSG_API -#define MEMP_NUM_TCPIP_MSG_API 8 -#endif - -/** - * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used - * for incoming packets. - * (only needed if you use tcpip.c) - */ -#ifndef MEMP_NUM_TCPIP_MSG_INPKT -#define MEMP_NUM_TCPIP_MSG_INPKT 8 -#endif - -/** - * MEMP_NUM_SNMP_NODE: the number of leafs in the SNMP tree. - */ -#ifndef MEMP_NUM_SNMP_NODE -#define MEMP_NUM_SNMP_NODE 50 -#endif - -/** - * MEMP_NUM_SNMP_ROOTNODE: the number of branches in the SNMP tree. - * Every branch has one leaf (MEMP_NUM_SNMP_NODE) at least! - */ -#ifndef MEMP_NUM_SNMP_ROOTNODE -#define MEMP_NUM_SNMP_ROOTNODE 30 -#endif - -/** - * MEMP_NUM_SNMP_VARBIND: the number of concurrent requests (does not have to - * be changed normally) - 2 of these are used per request (1 for input, - * 1 for output) - */ -#ifndef MEMP_NUM_SNMP_VARBIND -#define MEMP_NUM_SNMP_VARBIND 2 -#endif - -/** - * MEMP_NUM_SNMP_VALUE: the number of OID or values concurrently used - * (does not have to be changed normally) - 3 of these are used per request - * (1 for the value read and 2 for OIDs - input and output) - */ -#ifndef MEMP_NUM_SNMP_VALUE -#define MEMP_NUM_SNMP_VALUE 3 -#endif - -/** - * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls - * (before freeing the corresponding memory using lwip_freeaddrinfo()). - */ -#ifndef MEMP_NUM_NETDB -#define MEMP_NUM_NETDB 1 -#endif - -/** - * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list - * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. - */ -#ifndef MEMP_NUM_LOCALHOSTLIST -#define MEMP_NUM_LOCALHOSTLIST 1 -#endif - -/** - * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE - * interfaces (only used with PPPOE_SUPPORT==1) - */ -#ifndef MEMP_NUM_PPPOE_INTERFACES -#define MEMP_NUM_PPPOE_INTERFACES 1 -#endif - -/** - * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. - */ -#ifndef PBUF_POOL_SIZE -#define PBUF_POOL_SIZE 16 -#endif - -/* - --------------------------------- - ---------- ARP options ---------- - --------------------------------- -*/ -/** - * LWIP_ARP==1: Enable ARP functionality. - */ -#ifndef LWIP_ARP -#define LWIP_ARP 1 -#endif - -/** - * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. - */ -#ifndef ARP_TABLE_SIZE -#define ARP_TABLE_SIZE 10 -#endif - -/** - * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address - * resolution. By default, only the most recent packet is queued per IP address. - * This is sufficient for most protocols and mainly reduces TCP connection - * startup time. Set this to 1 if you know your application sends more than one - * packet in a row to an IP address that is not in the ARP cache. - */ -#ifndef ARP_QUEUEING -#define ARP_QUEUEING 0 -#endif - -/** - * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be - * updated with the source MAC and IP addresses supplied in the packet. - * You may want to disable this if you do not trust LAN peers to have the - * correct addresses, or as a limited approach to attempt to handle - * spoofing. If disabled, lwIP will need to make a new ARP request if - * the peer is not already in the ARP table, adding a little latency. - * The peer *is* in the ARP table if it requested our address before. - * Also notice that this slows down input processing of every IP packet! - */ -#ifndef ETHARP_TRUST_IP_MAC -#define ETHARP_TRUST_IP_MAC 0 -#endif - -/** - * ETHARP_SUPPORT_VLAN==1: support receiving ethernet packets with VLAN header. - * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. - * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. - * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. - * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan) - * that returns 1 to accept a packet or 0 to drop a packet. - */ -#ifndef ETHARP_SUPPORT_VLAN -#define ETHARP_SUPPORT_VLAN 0 -#endif - -/** LWIP_ETHERNET==1: enable ethernet support for PPPoE even though ARP - * might be disabled - */ -#ifndef LWIP_ETHERNET -#define LWIP_ETHERNET (LWIP_ARP || PPPOE_SUPPORT) -#endif - -/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure - * alignment of payload after that header. Since the header is 14 bytes long, - * without this padding e.g. addresses in the IP header will not be aligned - * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. - */ -#ifndef ETH_PAD_SIZE -#define ETH_PAD_SIZE 0 -#endif - -/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table - * entries (using etharp_add_static_entry/etharp_remove_static_entry). - */ -#ifndef ETHARP_SUPPORT_STATIC_ENTRIES -#define ETHARP_SUPPORT_STATIC_ENTRIES 0 -#endif - - -/* - -------------------------------- - ---------- IP options ---------- - -------------------------------- -*/ -/** - * IP_FORWARD==1: Enables the ability to forward IP packets across network - * interfaces. If you are going to run lwIP on a device with only one network - * interface, define this to 0. - */ -#ifndef IP_FORWARD -#define IP_FORWARD 0 -#endif - -/** - * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. - * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. - * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). - */ -#ifndef IP_OPTIONS_ALLOWED -#define IP_OPTIONS_ALLOWED 1 -#endif - -/** - * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that - * this option does not affect outgoing packet sizes, which can be controlled - * via IP_FRAG. - */ -#ifndef IP_REASSEMBLY -#define IP_REASSEMBLY 1 -#endif - -/** - * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note - * that this option does not affect incoming packet sizes, which can be - * controlled via IP_REASSEMBLY. - */ -#ifndef IP_FRAG -#define IP_FRAG 1 -#endif - -/** - * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) - * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived - * in this time, the whole packet is discarded. - */ -#ifndef IP_REASS_MAXAGE -#define IP_REASS_MAXAGE 3 -#endif - -/** - * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. - * Since the received pbufs are enqueued, be sure to configure - * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive - * packets even if the maximum amount of fragments is enqueued for reassembly! - */ -#ifndef IP_REASS_MAX_PBUFS -#define IP_REASS_MAX_PBUFS 10 -#endif - -/** - * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP - * fragmentation. Otherwise pbufs are allocated and reference the original - * packet data to be fragmented (or with LWIP_NETIF_TX_SINGLE_PBUF==1, - * new PBUF_RAM pbufs are used for fragments). - * ATTENTION: IP_FRAG_USES_STATIC_BUF==1 may not be used for DMA-enabled MACs! - */ -#ifndef IP_FRAG_USES_STATIC_BUF -#define IP_FRAG_USES_STATIC_BUF 0 -#endif - -/** - * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer - * (requires IP_FRAG_USES_STATIC_BUF==1) - */ -#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU) -#define IP_FRAG_MAX_MTU 1500 -#endif - -/** - * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. - */ -#ifndef IP_DEFAULT_TTL -#define IP_DEFAULT_TTL 255 -#endif - -/** - * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast - * filter per pcb on udp and raw send operations. To enable broadcast filter - * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. - */ -#ifndef IP_SOF_BROADCAST -#define IP_SOF_BROADCAST 0 -#endif - -/** - * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast - * filter on recv operations. - */ -#ifndef IP_SOF_BROADCAST_RECV -#define IP_SOF_BROADCAST_RECV 0 -#endif - -/** - * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back - * out on the netif where it was received. This should only be used for - * wireless networks. - * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming - * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags! - */ -#ifndef IP_FORWARD_ALLOW_TX_ON_RX_NETIF -#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 -#endif - -/** - * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first - * local TCP/UDP pcb (default==0). This can prevent creating predictable port - * numbers after booting a device. - */ -#ifndef LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS -#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 0 -#endif - -/* - ---------------------------------- - ---------- ICMP options ---------- - ---------------------------------- -*/ -/** - * LWIP_ICMP==1: Enable ICMP module inside the IP stack. - * Be careful, disable that make your product non-compliant to RFC1122 - */ -#ifndef LWIP_ICMP -#define LWIP_ICMP 1 -#endif - -/** - * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. - */ -#ifndef ICMP_TTL -#define ICMP_TTL (IP_DEFAULT_TTL) -#endif - -/** - * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) - */ -#ifndef LWIP_BROADCAST_PING -#define LWIP_BROADCAST_PING 0 -#endif - -/** - * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) - */ -#ifndef LWIP_MULTICAST_PING -#define LWIP_MULTICAST_PING 0 -#endif - -/* - --------------------------------- - ---------- RAW options ---------- - --------------------------------- -*/ -/** - * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. - */ -#ifndef LWIP_RAW -#define LWIP_RAW 1 -#endif - -/** - * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. - */ -#ifndef RAW_TTL -#define RAW_TTL (IP_DEFAULT_TTL) -#endif - -/* - ---------------------------------- - ---------- DHCP options ---------- - ---------------------------------- -*/ -/** - * LWIP_DHCP==1: Enable DHCP module. - */ -#ifndef LWIP_DHCP -#define LWIP_DHCP 0 -#endif - -/** - * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. - */ -#ifndef DHCP_DOES_ARP_CHECK -#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) -#endif - -/* - ------------------------------------ - ---------- AUTOIP options ---------- - ------------------------------------ -*/ -/** - * LWIP_AUTOIP==1: Enable AUTOIP module. - */ -#ifndef LWIP_AUTOIP -#define LWIP_AUTOIP 0 -#endif - -/** - * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on - * the same interface at the same time. - */ -#ifndef LWIP_DHCP_AUTOIP_COOP -#define LWIP_DHCP_AUTOIP_COOP 0 -#endif - -/** - * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes - * that should be sent before falling back on AUTOIP. This can be set - * as low as 1 to get an AutoIP address very quickly, but you should - * be prepared to handle a changing IP address when DHCP overrides - * AutoIP. - */ -#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES -#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 -#endif - -/* - ---------------------------------- - ---------- SNMP options ---------- - ---------------------------------- -*/ -/** - * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP - * transport. - */ -#ifndef LWIP_SNMP -#define LWIP_SNMP 0 -#endif - -/** - * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will - * allow. At least one request buffer is required. - * Does not have to be changed unless external MIBs answer request asynchronously - */ -#ifndef SNMP_CONCURRENT_REQUESTS -#define SNMP_CONCURRENT_REQUESTS 1 -#endif - -/** - * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap - * destination is required - */ -#ifndef SNMP_TRAP_DESTINATIONS -#define SNMP_TRAP_DESTINATIONS 1 -#endif - -/** - * SNMP_PRIVATE_MIB: - * When using a private MIB, you have to create a file 'private_mib.h' that contains - * a 'struct mib_array_node mib_private' which contains your MIB. - */ -#ifndef SNMP_PRIVATE_MIB -#define SNMP_PRIVATE_MIB 0 -#endif - -/** - * Only allow SNMP write actions that are 'safe' (e.g. disabeling netifs is not - * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). - * Unsafe requests are disabled by default! - */ -#ifndef SNMP_SAFE_REQUESTS -#define SNMP_SAFE_REQUESTS 1 -#endif - -/** - * The maximum length of strings used. This affects the size of - * MEMP_SNMP_VALUE elements. - */ -#ifndef SNMP_MAX_OCTET_STRING_LEN -#define SNMP_MAX_OCTET_STRING_LEN 127 -#endif - -/** - * The maximum depth of the SNMP tree. - * With private MIBs enabled, this depends on your MIB! - * This affects the size of MEMP_SNMP_VALUE elements. - */ -#ifndef SNMP_MAX_TREE_DEPTH -#define SNMP_MAX_TREE_DEPTH 15 -#endif - -/** - * The size of the MEMP_SNMP_VALUE elements, normally calculated from - * SNMP_MAX_OCTET_STRING_LEN and SNMP_MAX_TREE_DEPTH. - */ -#ifndef SNMP_MAX_VALUE_SIZE -#define SNMP_MAX_VALUE_SIZE LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN)+1, sizeof(s32_t)*(SNMP_MAX_TREE_DEPTH)) -#endif - -/* - ---------------------------------- - ---------- IGMP options ---------- - ---------------------------------- -*/ -/** - * LWIP_IGMP==1: Turn on IGMP module. - */ -#ifndef LWIP_IGMP -#define LWIP_IGMP 0 -#endif - -/* - ---------------------------------- - ---------- DNS options ----------- - ---------------------------------- -*/ -/** - * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS - * transport. - */ -#ifndef LWIP_DNS -#define LWIP_DNS 0 -#endif - -/** DNS maximum number of entries to maintain locally. */ -#ifndef DNS_TABLE_SIZE -#define DNS_TABLE_SIZE 4 -#endif - -/** DNS maximum host name length supported in the name table. */ -#ifndef DNS_MAX_NAME_LENGTH -#define DNS_MAX_NAME_LENGTH 256 -#endif - -/** The maximum of DNS servers */ -#ifndef DNS_MAX_SERVERS -#define DNS_MAX_SERVERS 2 -#endif - -/** DNS do a name checking between the query and the response. */ -#ifndef DNS_DOES_NAME_CHECK -#define DNS_DOES_NAME_CHECK 1 -#endif - -/** DNS message max. size. Default value is RFC compliant. */ -#ifndef DNS_MSG_SIZE -#define DNS_MSG_SIZE 512 -#endif - -/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, - * you have to define - * #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}} - * (an array of structs name/address, where address is an u32_t in network - * byte order). - * - * Instead, you can also use an external function: - * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name) - * that returns the IP address or INADDR_NONE if not found. - */ -#ifndef DNS_LOCAL_HOSTLIST -#define DNS_LOCAL_HOSTLIST 0 -#endif /* DNS_LOCAL_HOSTLIST */ - -/** If this is turned on, the local host-list can be dynamically changed - * at runtime. */ -#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC -#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -/* - --------------------------------- - ---------- UDP options ---------- - --------------------------------- -*/ -/** - * LWIP_UDP==1: Turn on UDP. - */ -#ifndef LWIP_UDP -#define LWIP_UDP 1 -#endif - -#ifndef LWIP_SO_LINGER -#define LWIP_SO_LINGER 1 -#endif - -/** - * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) - */ -#ifndef LWIP_UDPLITE -#define LWIP_UDPLITE 0 -#endif - -/** - * UDP_TTL: Default Time-To-Live value. - */ -#ifndef UDP_TTL -#define UDP_TTL (IP_DEFAULT_TTL) -#endif - -/** - * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. - */ -#ifndef LWIP_NETBUF_RECVINFO -#define LWIP_NETBUF_RECVINFO 0 -#endif - -/* - --------------------------------- - ---------- TCP options ---------- - --------------------------------- -*/ -/** - * LWIP_TCP==1: Turn on TCP. - */ -#ifndef LWIP_TCP -#define LWIP_TCP 1 -#endif - -/** - * TCP_TTL: Default Time-To-Live value. - */ -#ifndef TCP_TTL -#define TCP_TTL (IP_DEFAULT_TTL) -#endif - -/** - * TCP_WND: The size of a TCP window. This must be at least - * (2 * TCP_MSS) for things to work well - */ -#ifndef TCP_WND -#define TCP_WND (4 * TCP_MSS) -#endif - -/** - * TCP_MAXRTX: Maximum number of retransmissions of data segments. - */ -#ifndef TCP_MAXRTX -#define TCP_MAXRTX 12 -#endif - -/** - * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. - */ -#ifndef TCP_SYNMAXRTX -#define TCP_SYNMAXRTX 6 -#endif - -/** - * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. - * Define to 0 if your device is low on memory. - */ -#ifndef TCP_QUEUE_OOSEQ -#define TCP_QUEUE_OOSEQ (LWIP_TCP) -#endif - -/** - * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, - * you might want to increase this.) - * For the receive side, this MSS is advertised to the remote side - * when opening a connection. For the transmit size, this MSS sets - * an upper limit on the MSS advertised by the remote host. - */ -#ifndef TCP_MSS -#define TCP_MSS 536 -#endif - -/** - * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really - * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which - * reflects the available reassembly buffer size at the remote host) and the - * largest size permitted by the IP layer" (RFC 1122) - * Setting this to 1 enables code that checks TCP_MSS against the MTU of the - * netif used for a connection and limits the MSS if it would be too big otherwise. - */ -#ifndef TCP_CALCULATE_EFF_SEND_MSS -#define TCP_CALCULATE_EFF_SEND_MSS 1 -#endif - - -/** - * TCP_SND_BUF: TCP sender buffer space (bytes). - * To achieve good performance, this should be at least 2 * TCP_MSS. - */ -#ifndef TCP_SND_BUF -#define TCP_SND_BUF (2 * TCP_MSS) -#endif - -/** - * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least - * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. - */ -#ifndef TCP_SND_QUEUELEN -#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) -#endif - -/** - * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than - * TCP_SND_BUF. It is the amount of space which must be available in the - * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). - */ -#ifndef TCP_SNDLOWAT -#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) -#endif - -/** - * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less - * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below - * this number, select returns writable (combined with TCP_SNDLOWAT). - */ -#ifndef TCP_SNDQUEUELOWAT -#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) -#endif - -/** - * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb. - * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. - */ -#ifndef TCP_OOSEQ_MAX_BYTES -#define TCP_OOSEQ_MAX_BYTES 0 -#endif - -/** - * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb. - * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. - */ -#ifndef TCP_OOSEQ_MAX_PBUFS -#define TCP_OOSEQ_MAX_PBUFS 0 -#endif - -/** - * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. - */ -#ifndef TCP_LISTEN_BACKLOG -#define TCP_LISTEN_BACKLOG 0 -#endif - -/** - * The maximum allowed backlog for TCP listen netconns. - * This backlog is used unless another is explicitly specified. - * 0xff is the maximum (u8_t). - */ -#ifndef TCP_DEFAULT_LISTEN_BACKLOG -#define TCP_DEFAULT_LISTEN_BACKLOG 0xff -#endif - -/** - * TCP_OVERSIZE: The maximum number of bytes that tcp_write may - * allocate ahead of time in an attempt to create shorter pbuf chains - * for transmission. The meaningful range is 0 to TCP_MSS. Some - * suggested values are: - * - * 0: Disable oversized allocation. Each tcp_write() allocates a new - pbuf (old behaviour). - * 1: Allocate size-aligned pbufs with minimal excess. Use this if your - * scatter-gather DMA requires aligned fragments. - * 128: Limit the pbuf/memory overhead to 20%. - * TCP_MSS: Try to create unfragmented TCP packets. - * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. - */ -#ifndef TCP_OVERSIZE -#define TCP_OVERSIZE TCP_MSS -#endif - -/** - * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. - */ -#ifndef LWIP_TCP_TIMESTAMPS -#define LWIP_TCP_TIMESTAMPS 0 -#endif - -/** - * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an - * explicit window update - */ -#ifndef TCP_WND_UPDATE_THRESHOLD -#define TCP_WND_UPDATE_THRESHOLD (TCP_WND / 4) -#endif - -/** - * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. - * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all - * events (accept, sent, etc) that happen in the system. - * LWIP_CALLBACK_API==1: The PCB callback function is called directly - * for the event. This is the default. - */ -#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) -#define LWIP_EVENT_API 0 -#define LWIP_CALLBACK_API 1 -#endif - - -/* - ---------------------------------- - ---------- Pbuf options ---------- - ---------------------------------- -*/ -/** - * PBUF_LINK_HLEN: the number of bytes that should be allocated for a - * link level header. The default is 14, the standard value for - * Ethernet. - */ -#ifndef PBUF_LINK_HLEN -#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) -#endif - -/** - * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is - * designed to accomodate single full size TCP frame in one pbuf, including - * TCP_MSS, IP header, and link header. - */ -#ifndef PBUF_POOL_BUFSIZE -#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN) -#endif - -/* - ------------------------------------------------ - ---------- Network Interfaces options ---------- - ------------------------------------------------ -*/ -/** - * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname - * field. - */ -#ifndef LWIP_NETIF_HOSTNAME -#define LWIP_NETIF_HOSTNAME 0 -#endif - -/** - * LWIP_NETIF_API==1: Support netif api (in netifapi.c) - */ -#ifndef LWIP_NETIF_API -#define LWIP_NETIF_API 0 -#endif - -/** - * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface - * changes its up/down status (i.e., due to DHCP IP acquistion) - */ -#ifndef LWIP_NETIF_STATUS_CALLBACK -#define LWIP_NETIF_STATUS_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface - * whenever the link changes (i.e., link down) - */ -#ifndef LWIP_NETIF_LINK_CALLBACK -#define LWIP_NETIF_LINK_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called - * when a netif has been removed - */ -#ifndef LWIP_NETIF_REMOVE_CALLBACK -#define LWIP_NETIF_REMOVE_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table - * indices) in struct netif. TCP and UDP can make use of this to prevent - * scanning the ARP table for every sent packet. While this is faster for big - * ARP tables or many concurrent connections, it might be counterproductive - * if you have a tiny ARP table or if there never are concurrent connections. - */ -#ifndef LWIP_NETIF_HWADDRHINT -#define LWIP_NETIF_HWADDRHINT 0 -#endif - -/** - * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP - * address equal to the netif IP address, looping them back up the stack. - */ -#ifndef LWIP_NETIF_LOOPBACK -#define LWIP_NETIF_LOOPBACK 0 -#endif - -/** - * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback - * sending for each netif (0 = disabled) - */ -#ifndef LWIP_LOOPBACK_MAX_PBUFS -#define LWIP_LOOPBACK_MAX_PBUFS 0 -#endif - -/** - * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in - * the system, as netifs must change how they behave depending on this setting - * for the LWIP_NETIF_LOOPBACK option to work. - * Setting this is needed to avoid reentering non-reentrant functions like - * tcp_input(). - * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a - * multithreaded environment like tcpip.c. In this case, netif->input() - * is called directly. - * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. - * The packets are put on a list and netif_poll() must be called in - * the main application loop. - */ -#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING -#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) -#endif - -/** - * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data - * to be sent into one single pbuf. This is for compatibility with DMA-enabled - * MACs that do not support scatter-gather. - * Beware that this might involve CPU-memcpy before transmitting that would not - * be needed without this flag! Use this only if you need to! - * - * @todo: TCP and IP-frag do not work with this, yet: - */ -#ifndef LWIP_NETIF_TX_SINGLE_PBUF -#define LWIP_NETIF_TX_SINGLE_PBUF 0 -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - -/* - ------------------------------------ - ---------- LOOPIF options ---------- - ------------------------------------ -*/ -/** - * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c - */ -#ifndef LWIP_HAVE_LOOPIF -#define LWIP_HAVE_LOOPIF 0 -#endif - -/* - ------------------------------------ - ---------- SLIPIF options ---------- - ------------------------------------ -*/ -/** - * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c - */ -#ifndef LWIP_HAVE_SLIPIF -#define LWIP_HAVE_SLIPIF 0 -#endif - -/* - ------------------------------------ - ---------- Thread options ---------- - ------------------------------------ -*/ -/** - * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. - */ -#ifndef TCPIP_THREAD_NAME -#define TCPIP_THREAD_NAME "tcpip_thread" -#endif - -/** - * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef TCPIP_THREAD_STACKSIZE -#define TCPIP_THREAD_STACKSIZE 0 -#endif - -/** - * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef TCPIP_THREAD_PRIO -#define TCPIP_THREAD_PRIO 1 -#endif - -/** - * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when tcpip_init is called. - */ -#ifndef TCPIP_MBOX_SIZE -#define TCPIP_MBOX_SIZE 0 -#endif - -/** - * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. - */ -#ifndef SLIPIF_THREAD_NAME -#define SLIPIF_THREAD_NAME "slipif_loop" -#endif - -/** - * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef SLIPIF_THREAD_STACKSIZE -#define SLIPIF_THREAD_STACKSIZE 0 -#endif - -/** - * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef SLIPIF_THREAD_PRIO -#define SLIPIF_THREAD_PRIO 1 -#endif - -/** - * PPP_THREAD_NAME: The name assigned to the pppInputThread. - */ -#ifndef PPP_THREAD_NAME -#define PPP_THREAD_NAME "pppInputThread" -#endif - -/** - * PPP_THREAD_STACKSIZE: The stack size used by the pppInputThread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef PPP_THREAD_STACKSIZE -#define PPP_THREAD_STACKSIZE 0 -#endif - -/** - * PPP_THREAD_PRIO: The priority assigned to the pppInputThread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef PPP_THREAD_PRIO -#define PPP_THREAD_PRIO 1 -#endif - -/** - * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. - */ -#ifndef DEFAULT_THREAD_NAME -#define DEFAULT_THREAD_NAME "lwIP" -#endif - -/** - * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef DEFAULT_THREAD_STACKSIZE -#define DEFAULT_THREAD_STACKSIZE 0 -#endif - -/** - * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#ifndef DEFAULT_THREAD_PRIO -#define DEFAULT_THREAD_PRIO 1 -#endif - -/** - * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#ifndef DEFAULT_RAW_RECVMBOX_SIZE -#define DEFAULT_RAW_RECVMBOX_SIZE 0 -#endif - -/** - * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#ifndef DEFAULT_UDP_RECVMBOX_SIZE -#define DEFAULT_UDP_RECVMBOX_SIZE 0 -#endif - -/** - * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#ifndef DEFAULT_TCP_RECVMBOX_SIZE -#define DEFAULT_TCP_RECVMBOX_SIZE 0 -#endif - -/** - * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when the acceptmbox is created. - */ -#ifndef DEFAULT_ACCEPTMBOX_SIZE -#define DEFAULT_ACCEPTMBOX_SIZE 0 -#endif - -/* - ---------------------------------------------- - ---------- Sequential layer options ---------- - ---------------------------------------------- -*/ -/** - * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) - * Don't use it if you're not an active lwIP project member - */ -#ifndef LWIP_TCPIP_CORE_LOCKING -#define LWIP_TCPIP_CORE_LOCKING 0 -#endif - -/** - * LWIP_TCPIP_CORE_LOCKING_INPUT: (EXPERIMENTAL!) - * Don't use it if you're not an active lwIP project member - */ -#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT -#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 -#endif - -/** - * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) - */ -#ifndef LWIP_NETCONN -#define LWIP_NETCONN 1 -#endif - -/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout tod create - * timers running in tcpip_thread from another thread. - */ -#ifndef LWIP_TCPIP_TIMEOUT -#define LWIP_TCPIP_TIMEOUT 1 -#endif - -/* - ------------------------------------ - ---------- Socket options ---------- - ------------------------------------ -*/ -/** - * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) - */ -#ifndef LWIP_SOCKET -#define LWIP_SOCKET 1 -#endif - -/** - * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names. - * (only used if you use sockets.c) - */ -#ifndef LWIP_COMPAT_SOCKETS -#define LWIP_COMPAT_SOCKETS 1 -#endif - -/** - * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. - * Disable this option if you use a POSIX operating system that uses the same - * names (read, write & close). (only used if you use sockets.c) - */ -#ifndef LWIP_POSIX_SOCKETS_IO_NAMES -#define LWIP_POSIX_SOCKETS_IO_NAMES 1 -#endif - -/** - * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT - * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set - * in seconds. (does not require sockets.c, and will affect tcp.c) - */ -#ifndef LWIP_TCP_KEEPALIVE -#define LWIP_TCP_KEEPALIVE 0 -#endif - -/** - * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and - * SO_SNDTIMEO processing. - */ -#ifndef LWIP_SO_SNDTIMEO -#define LWIP_SO_SNDTIMEO 0 -#endif - -/** - * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and - * SO_RCVTIMEO processing. - */ -#ifndef LWIP_SO_RCVTIMEO -#define LWIP_SO_RCVTIMEO 0 -#endif - -/** - * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. - */ -#ifndef LWIP_SO_RCVBUF -#define LWIP_SO_RCVBUF 0 -#endif - -/** - * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. - */ -#ifndef RECV_BUFSIZE_DEFAULT -#define RECV_BUFSIZE_DEFAULT INT_MAX -#endif - -/** - * SO_REUSE==1: Enable SO_REUSEADDR option. - */ -#ifndef SO_REUSE -#define SO_REUSE 0 -#endif - -/** - * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets - * to all local matches if SO_REUSEADDR is turned on. - * WARNING: Adds a memcpy for every packet if passing to more than one pcb! - */ -#ifndef SO_REUSE_RXTOALL -#define SO_REUSE_RXTOALL 0 -#endif - -/** - * LWIP_FIONREAD_LINUXMODE==0 (default): ioctl/FIONREAD returns the amount of - * pending data in the network buffer. This is the way windows does it. It's - * the default for lwIP since it is smaller. - * LWIP_FIONREAD_LINUXMODE==1: ioctl/FIONREAD returns the size of the next - * pending datagram in bytes. This is the way linux does it. This code is only - * here for compatibility. - */ -#ifndef LWIP_FIONREAD_LINUXMODE -#define LWIP_FIONREAD_LINUXMODE 0 -#endif - -/* - ---------------------------------------- - ---------- Statistics options ---------- - ---------------------------------------- -*/ -/** - * LWIP_STATS==1: Enable statistics collection in lwip_stats. - */ -#ifndef LWIP_STATS -#define LWIP_STATS 1 -#endif - -#if LWIP_STATS - -/** - * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. - */ -#ifndef LWIP_STATS_DISPLAY -#define LWIP_STATS_DISPLAY 0 -#endif - -/** - * LINK_STATS==1: Enable link stats. - */ -#ifndef LINK_STATS -#define LINK_STATS 1 -#endif - -/** - * ETHARP_STATS==1: Enable etharp stats. - */ -#ifndef ETHARP_STATS -#define ETHARP_STATS (LWIP_ARP) -#endif - -/** - * IP_STATS==1: Enable IP stats. - */ -#ifndef IP_STATS -#define IP_STATS 1 -#endif - -/** - * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is - * on if using either frag or reass. - */ -#ifndef IPFRAG_STATS -#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) -#endif - -/** - * ICMP_STATS==1: Enable ICMP stats. - */ -#ifndef ICMP_STATS -#define ICMP_STATS 1 -#endif - -/** - * IGMP_STATS==1: Enable IGMP stats. - */ -#ifndef IGMP_STATS -#define IGMP_STATS (LWIP_IGMP) -#endif - -/** - * UDP_STATS==1: Enable UDP stats. Default is on if - * UDP enabled, otherwise off. - */ -#ifndef UDP_STATS -#define UDP_STATS (LWIP_UDP) -#endif - -/** - * TCP_STATS==1: Enable TCP stats. Default is on if TCP - * enabled, otherwise off. - */ -#ifndef TCP_STATS -#define TCP_STATS (LWIP_TCP) -#endif - -/** - * MEM_STATS==1: Enable mem.c stats. - */ -#ifndef MEM_STATS -#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) -#endif - -/** - * MEMP_STATS==1: Enable memp.c pool stats. - */ -#ifndef MEMP_STATS -#define MEMP_STATS (MEMP_MEM_MALLOC == 0) -#endif - -/** - * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). - */ -#ifndef SYS_STATS -#define SYS_STATS (NO_SYS == 0) -#endif - -/** - * IP6_STATS==1: Enable IPv6 stats. - */ -#ifndef IP6_STATS -#define IP6_STATS (LWIP_IPV6) -#endif - -/** - * ICMP6_STATS==1: Enable ICMP for IPv6 stats. - */ -#ifndef ICMP6_STATS -#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6) -#endif - -/** - * IP6_FRAG_STATS==1: Enable IPv6 fragmentation stats. - */ -#ifndef IP6_FRAG_STATS -#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS)) -#endif - -/** - * MLD6_STATS==1: Enable MLD for IPv6 stats. - */ -#ifndef MLD6_STATS -#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD) -#endif - -/** - * ND6_STATS==1: Enable Neighbor discovery for IPv6 stats. - */ -#ifndef ND6_STATS -#define ND6_STATS (LWIP_IPV6) -#endif - -#else - -#define LINK_STATS 0 -#define ETHARP_STATS 0 -#define IP_STATS 0 -#define IPFRAG_STATS 0 -#define ICMP_STATS 0 -#define IGMP_STATS 0 -#define UDP_STATS 0 -#define TCP_STATS 0 -#define MEM_STATS 0 -#define MEMP_STATS 0 -#define SYS_STATS 0 -#define LWIP_STATS_DISPLAY 0 -#define IP6_STATS 0 -#define ICMP6_STATS 0 -#define IP6_FRAG_STATS 0 -#define MLD6_STATS 0 -#define ND6_STATS 0 - -#endif /* LWIP_STATS */ - -/* - --------------------------------- - ---------- PPP options ---------- - --------------------------------- -*/ -/** - * PPP_SUPPORT==1: Enable PPP. - */ -#ifndef PPP_SUPPORT -#define PPP_SUPPORT 0 -#endif - -/** - * PPPOE_SUPPORT==1: Enable PPP Over Ethernet - */ -#ifndef PPPOE_SUPPORT -#define PPPOE_SUPPORT 0 -#endif - -/** - * PPPOS_SUPPORT==1: Enable PPP Over Serial - */ -#ifndef PPPOS_SUPPORT -#define PPPOS_SUPPORT PPP_SUPPORT -#endif - -#if PPP_SUPPORT - -/** - * NUM_PPP: Max PPP sessions. - */ -#ifndef NUM_PPP -#define NUM_PPP 1 -#endif - -/** - * PAP_SUPPORT==1: Support PAP. - */ -#ifndef PAP_SUPPORT -#define PAP_SUPPORT 0 -#endif - -/** - * CHAP_SUPPORT==1: Support CHAP. - */ -#ifndef CHAP_SUPPORT -#define CHAP_SUPPORT 0 -#endif - -/** - * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef MSCHAP_SUPPORT -#define MSCHAP_SUPPORT 0 -#endif - -/** - * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef CBCP_SUPPORT -#define CBCP_SUPPORT 0 -#endif - -/** - * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef CCP_SUPPORT -#define CCP_SUPPORT 0 -#endif - -/** - * VJ_SUPPORT==1: Support VJ header compression. - */ -#ifndef VJ_SUPPORT -#define VJ_SUPPORT 0 -#endif - -/** - * MD5_SUPPORT==1: Support MD5 (see also CHAP). - */ -#ifndef MD5_SUPPORT -#define MD5_SUPPORT 0 -#endif - -/* - * Timeouts - */ -#ifndef FSM_DEFTIMEOUT -#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ -#endif - -#ifndef FSM_DEFMAXTERMREQS -#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ -#endif - -#ifndef FSM_DEFMAXCONFREQS -#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ -#endif - -#ifndef FSM_DEFMAXNAKLOOPS -#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ -#endif - -#ifndef UPAP_DEFTIMEOUT -#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ -#endif - -#ifndef UPAP_DEFREQTIME -#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ -#endif - -#ifndef CHAP_DEFTIMEOUT -#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ -#endif - -#ifndef CHAP_DEFTRANSMITS -#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ -#endif - -/* Interval in seconds between keepalive echo requests, 0 to disable. */ -#ifndef LCP_ECHOINTERVAL -#define LCP_ECHOINTERVAL 0 -#endif - -/* Number of unanswered echo requests before failure. */ -#ifndef LCP_MAXECHOFAILS -#define LCP_MAXECHOFAILS 3 -#endif - -/* Max Xmit idle time (in jiffies) before resend flag char. */ -#ifndef PPP_MAXIDLEFLAG -#define PPP_MAXIDLEFLAG 100 -#endif - -/* - * Packet sizes - * - * Note - lcp shouldn't be allowed to negotiate stuff outside these - * limits. See lcp.h in the pppd directory. - * (XXX - these constants should simply be shared by lcp.c instead - * of living in lcp.h) - */ -#define PPP_MTU 1500 /* Default MTU (size of Info field) */ -#ifndef PPP_MAXMTU -/* #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) */ -#define PPP_MAXMTU 1500 /* Largest MTU we allow */ -#endif -#define PPP_MINMTU 64 -#define PPP_MRU 1500 /* default MRU = max length of info field */ -#define PPP_MAXMRU 1500 /* Largest MRU we allow */ -#ifndef PPP_DEFMRU -#define PPP_DEFMRU 296 /* Try for this */ -#endif -#define PPP_MINMRU 128 /* No MRUs below this */ - -#ifndef MAXNAMELEN -#define MAXNAMELEN 256 /* max length of hostname or name for auth */ -#endif -#ifndef MAXSECRETLEN -#define MAXSECRETLEN 256 /* max length of password or secret */ -#endif - -#endif /* PPP_SUPPORT */ - -/* - -------------------------------------- - ---------- Checksum options ---------- - -------------------------------------- -*/ -/** - * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. - */ -#ifndef CHECKSUM_GEN_IP -#define CHECKSUM_GEN_IP 1 -#endif - -/** - * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. - */ -#ifndef CHECKSUM_GEN_UDP -#define CHECKSUM_GEN_UDP 1 -#endif - -/** - * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. - */ -#ifndef CHECKSUM_GEN_TCP -#define CHECKSUM_GEN_TCP 1 -#endif - -/** - * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets. - */ -#ifndef CHECKSUM_GEN_ICMP -#define CHECKSUM_GEN_ICMP 1 -#endif - -/** - * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. - */ -#ifndef CHECKSUM_CHECK_IP -#define CHECKSUM_CHECK_IP 1 -#endif - -/** - * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. - */ -#ifndef CHECKSUM_CHECK_UDP -#define CHECKSUM_CHECK_UDP 1 -#endif - -/** - * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. - */ -#ifndef CHECKSUM_CHECK_TCP -#define CHECKSUM_CHECK_TCP 1 -#endif - -/** - * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from - * application buffers to pbufs. - */ -#ifndef LWIP_CHECKSUM_ON_COPY -#define LWIP_CHECKSUM_ON_COPY 0 -#endif - -/* - --------------------------------------- - ---------- IPv6 options --------------- - --------------------------------------- -*/ -/** - * LWIP_IPV6==1: Enable IPv6 - */ -#ifndef LWIP_IPV6 -#define LWIP_IPV6 0 -#endif - -/** - * LWIP_IPV6_NUM_ADDRESSES: Number of IPv6 addresses per netif. - */ -#ifndef LWIP_IPV6_NUM_ADDRESSES -#define LWIP_IPV6_NUM_ADDRESSES 3 -#endif - -/** - * LWIP_IPV6_FORWARD==1: Forward IPv6 packets across netifs - */ -#ifndef LWIP_IPV6_FORWARD -#define LWIP_IPV6_FORWARD 0 -#endif - -/** - * LWIP_ICMP6==1: Enable ICMPv6 (mandatory per RFC) - */ -#ifndef LWIP_ICMP6 -#define LWIP_ICMP6 (LWIP_IPV6) -#endif - -/** - * LWIP_ICMP6_DATASIZE: bytes from original packet to send back in - * ICMPv6 error messages. - */ -#ifndef LWIP_ICMP6_DATASIZE -#define LWIP_ICMP6_DATASIZE 8 -#endif - -/** - * LWIP_ICMP6_HL: default hop limit for ICMPv6 messages - */ -#ifndef LWIP_ICMP6_HL -#define LWIP_ICMP6_HL 255 -#endif - -/** - * LWIP_ICMP6_CHECKSUM_CHECK==1: verify checksum on ICMPv6 packets - */ -#ifndef LWIP_ICMP6_CHECKSUM_CHECK -#define LWIP_ICMP6_CHECKSUM_CHECK 1 -#endif - -/** - * LWIP_IPV6_MLD==1: Enable multicast listener discovery protocol. - */ -#ifndef LWIP_IPV6_MLD -#define LWIP_IPV6_MLD (LWIP_IPV6) -#endif - -/** - * MEMP_NUM_MLD6_GROUP: Max number of IPv6 multicast that can be joined. - */ -#ifndef MEMP_NUM_MLD6_GROUP -#define MEMP_NUM_MLD6_GROUP 4 -#endif - -/** - * LWIP_IPV6_FRAG==1: Fragment outgoing IPv6 packets that are too big. - */ -#ifndef LWIP_IPV6_FRAG -#define LWIP_IPV6_FRAG 0 -#endif - -/** - * LWIP_IPV6_REASS==1: reassemble incoming IPv6 packets that fragmented - */ -#ifndef LWIP_IPV6_REASS -#define LWIP_IPV6_REASS (LWIP_IPV6) -#endif - -/** - * LWIP_ND6_QUEUEING==1: queue outgoing IPv6 packets while MAC address - * is being resolved. - */ -#ifndef LWIP_ND6_QUEUEING -#define LWIP_ND6_QUEUEING (LWIP_IPV6) -#endif - -/** - * MEMP_NUM_ND6_QUEUE: Max number of IPv6 packets to queue during MAC resolution. - */ -#ifndef MEMP_NUM_ND6_QUEUE -#define MEMP_NUM_ND6_QUEUE 20 -#endif - -/** - * LWIP_ND6_NUM_NEIGHBORS: Number of entries in IPv6 neighbor cache - */ -#ifndef LWIP_ND6_NUM_NEIGHBORS -#define LWIP_ND6_NUM_NEIGHBORS 10 -#endif - -/** - * LWIP_ND6_NUM_DESTINATIONS: number of entries in IPv6 destination cache - */ -#ifndef LWIP_ND6_NUM_DESTINATIONS -#define LWIP_ND6_NUM_DESTINATIONS 10 -#endif - -/** - * LWIP_ND6_NUM_PREFIXES: number of entries in IPv6 on-link prefixes cache - */ -#ifndef LWIP_ND6_NUM_PREFIXES -#define LWIP_ND6_NUM_PREFIXES 5 -#endif - -/** - * LWIP_ND6_NUM_ROUTERS: number of entries in IPv6 default router cache - */ -#ifndef LWIP_ND6_NUM_ROUTERS -#define LWIP_ND6_NUM_ROUTERS 3 -#endif - -/** - * LWIP_ND6_MAX_MULTICAST_SOLICIT: max number of multicast solicit messages to send - * (neighbor solicit and router solicit) - */ -#ifndef LWIP_ND6_MAX_MULTICAST_SOLICIT -#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3 -#endif - -/** - * LWIP_ND6_MAX_UNICAST_SOLICIT: max number of unicast neighbor solicitation messages - * to send during neighbor reachability detection. - */ -#ifndef LWIP_ND6_MAX_UNICAST_SOLICIT -#define LWIP_ND6_MAX_UNICAST_SOLICIT 3 -#endif - -/** - * Unused: See ND RFC (time in milliseconds). - */ -#ifndef LWIP_ND6_MAX_ANYCAST_DELAY_TIME -#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000 -#endif - -/** - * Unused: See ND RFC - */ -#ifndef LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT -#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3 -#endif - -/** - * LWIP_ND6_REACHABLE_TIME: default neighbor reachable time (in milliseconds). - * May be updated by router advertisement messages. - */ -#ifndef LWIP_ND6_REACHABLE_TIME -#define LWIP_ND6_REACHABLE_TIME 30000 -#endif - -/** - * LWIP_ND6_RETRANS_TIMER: default retransmission timer for solicitation messages - */ -#ifndef LWIP_ND6_RETRANS_TIMER -#define LWIP_ND6_RETRANS_TIMER 1000 -#endif - -/** - * LWIP_ND6_DELAY_FIRST_PROBE_TIME: Delay before first unicast neighbor solicitation - * message is sent, during neighbor reachability detection. - */ -#ifndef LWIP_ND6_DELAY_FIRST_PROBE_TIME -#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000 -#endif - -/** - * LWIP_ND6_ALLOW_RA_UPDATES==1: Allow Router Advertisement messages to update - * Reachable time and retransmission timers, and netif MTU. - */ -#ifndef LWIP_ND6_ALLOW_RA_UPDATES -#define LWIP_ND6_ALLOW_RA_UPDATES 1 -#endif - -/** - * LWIP_IPV6_SEND_ROUTER_SOLICIT==1: Send router solicitation messages during - * network startup. - */ -#ifndef LWIP_IPV6_SEND_ROUTER_SOLICIT -#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1 -#endif - -/** - * LWIP_ND6_TCP_REACHABILITY_HINTS==1: Allow TCP to provide Neighbor Discovery - * with reachability hints for connected destinations. This helps avoid sending - * unicast neighbor solicitation messages. - */ -#ifndef LWIP_ND6_TCP_REACHABILITY_HINTS -#define LWIP_ND6_TCP_REACHABILITY_HINTS 1 -#endif - -/** - * LWIP_IPV6_AUTOCONFIG==1: Enable stateless address autoconfiguration as per RFC 4862. - */ -#ifndef LWIP_IPV6_AUTOCONFIG -#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6) -#endif - -/** - * LWIP_IPV6_DUP_DETECT_ATTEMPTS: Number of duplicate address detection attempts. - */ -#ifndef LWIP_IPV6_DUP_DETECT_ATTEMPTS -#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1 -#endif - -/** - * LWIP_IPV6_DHCP6==1: enable DHCPv6 stateful address autoconfiguration. - */ -#ifndef LWIP_IPV6_DHCP6 -#define LWIP_IPV6_DHCP6 0 -#endif - -/* - --------------------------------------- - ---------- Hook options --------------- - --------------------------------------- -*/ - -/* Hooks are undefined by default, define them to a function if you need them. */ - -/** - * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): - * - called from ip_input() (IPv4) - * - pbuf: received struct pbuf passed to ip_input() - * - input_netif: struct netif on which the packet has been received - * Return values: - * - 0: Hook has not consumed the packet, packet is processed as normal - * - != 0: Hook has consumed the packet. - * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook - * (i.e. free it when done). - */ - -/** - * LWIP_HOOK_IP4_ROUTE(dest): - * - called from ip_route() (IPv4) - * - dest: destination IPv4 address - * Returns the destination netif or NULL if no destination netif is found. In - * that case, ip_route() continues as normal. - */ - -/* - --------------------------------------- - ---------- Debugging options ---------- - --------------------------------------- -*/ -/** - * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is - * compared against this value. If it is smaller, then debugging - * messages are written. - */ -#ifndef LWIP_DBG_MIN_LEVEL -#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL -#endif - -/** - * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable - * debug messages of certain types. - */ -#ifndef LWIP_DBG_TYPES_ON -#define LWIP_DBG_TYPES_ON LWIP_DBG_ON -#endif - -/** - * ETHARP_DEBUG: Enable debugging in etharp.c. - */ -#ifndef ETHARP_DEBUG -#define ETHARP_DEBUG LWIP_DBG_OFF -#endif - -/** - * NETIF_DEBUG: Enable debugging in netif.c. - */ -#ifndef NETIF_DEBUG -#define NETIF_DEBUG LWIP_DBG_OFF -#endif - -/** - * PBUF_DEBUG: Enable debugging in pbuf.c. - */ -#ifndef PBUF_DEBUG -#define PBUF_DEBUG LWIP_DBG_OFF -#endif - -/** - * API_LIB_DEBUG: Enable debugging in api_lib.c. - */ -#ifndef API_LIB_DEBUG -#define API_LIB_DEBUG LWIP_DBG_OFF -#endif - -/** - * API_MSG_DEBUG: Enable debugging in api_msg.c. - */ -#ifndef API_MSG_DEBUG -#define API_MSG_DEBUG LWIP_DBG_OFF -#endif - -/** - * SOCKETS_DEBUG: Enable debugging in sockets.c. - */ -#ifndef SOCKETS_DEBUG -#define SOCKETS_DEBUG LWIP_DBG_OFF -#endif - -/** - * ICMP_DEBUG: Enable debugging in icmp.c. - */ -#ifndef ICMP_DEBUG -#define ICMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * IGMP_DEBUG: Enable debugging in igmp.c. - */ -#ifndef IGMP_DEBUG -#define IGMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * INET_DEBUG: Enable debugging in inet.c. - */ -#ifndef INET_DEBUG -#define INET_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP_DEBUG: Enable debugging for IP. - */ -#ifndef IP_DEBUG -#define IP_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. - */ -#ifndef IP_REASS_DEBUG -#define IP_REASS_DEBUG LWIP_DBG_OFF -#endif - -/** - * RAW_DEBUG: Enable debugging in raw.c. - */ -#ifndef RAW_DEBUG -#define RAW_DEBUG LWIP_DBG_OFF -#endif - -/** - * MEM_DEBUG: Enable debugging in mem.c. - */ -#ifndef MEM_DEBUG -#define MEM_DEBUG LWIP_DBG_OFF -#endif - -/** - * MEMP_DEBUG: Enable debugging in memp.c. - */ -#ifndef MEMP_DEBUG -#define MEMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SYS_DEBUG: Enable debugging in sys.c. - */ -#ifndef SYS_DEBUG -#define SYS_DEBUG LWIP_DBG_OFF -#endif - -/** - * TIMERS_DEBUG: Enable debugging in timers.c. - */ -#ifndef TIMERS_DEBUG -#define TIMERS_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_DEBUG: Enable debugging for TCP. - */ -#ifndef TCP_DEBUG -#define TCP_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. - */ -#ifndef TCP_INPUT_DEBUG -#define TCP_INPUT_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. - */ -#ifndef TCP_FR_DEBUG -#define TCP_FR_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit - * timeout. - */ -#ifndef TCP_RTO_DEBUG -#define TCP_RTO_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. - */ -#ifndef TCP_CWND_DEBUG -#define TCP_CWND_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. - */ -#ifndef TCP_WND_DEBUG -#define TCP_WND_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. - */ -#ifndef TCP_OUTPUT_DEBUG -#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. - */ -#ifndef TCP_RST_DEBUG -#define TCP_RST_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. - */ -#ifndef TCP_QLEN_DEBUG -#define TCP_QLEN_DEBUG LWIP_DBG_OFF -#endif - -/** - * UDP_DEBUG: Enable debugging in UDP. - */ -#ifndef UDP_DEBUG -#define UDP_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCPIP_DEBUG: Enable debugging in tcpip.c. - */ -#ifndef TCPIP_DEBUG -#define TCPIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * PPP_DEBUG: Enable debugging for PPP. - */ -#ifndef PPP_DEBUG -#define PPP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SLIP_DEBUG: Enable debugging in slipif.c. - */ -#ifndef SLIP_DEBUG -#define SLIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * DHCP_DEBUG: Enable debugging in dhcp.c. - */ -#ifndef DHCP_DEBUG -#define DHCP_DEBUG LWIP_DBG_OFF -#endif - -/** - * AUTOIP_DEBUG: Enable debugging in autoip.c. - */ -#ifndef AUTOIP_DEBUG -#define AUTOIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SNMP_MSG_DEBUG: Enable debugging for SNMP messages. - */ -#ifndef SNMP_MSG_DEBUG -#define SNMP_MSG_DEBUG LWIP_DBG_OFF -#endif - -/** - * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. - */ -#ifndef SNMP_MIB_DEBUG -#define SNMP_MIB_DEBUG LWIP_DBG_OFF -#endif - -/** - * DNS_DEBUG: Enable debugging for DNS. - */ -#ifndef DNS_DEBUG -#define DNS_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP6_DEBUG: Enable debugging for IPv6. - */ -#ifndef IP6_DEBUG -#define IP6_DEBUG LWIP_DBG_OFF -#endif - -#endif /* __LWIP_OPT_H__ */ +/** + * @file + * + * lwIP Options Configuration + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_OPT_H__ +#define __LWIP_OPT_H__ + +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you dont like! + */ +#include "lwipopts.h" +#include "lwip/debug.h" + +/* + ----------------------------------------------- + ---------- Platform specific locking ---------- + ----------------------------------------------- +*/ + +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#ifndef SYS_LIGHTWEIGHT_PROT +#define SYS_LIGHTWEIGHT_PROT 0 +#endif + +/** + * NO_SYS==1: Provides VERY minimal functionality. Otherwise, + * use lwIP facilities. + */ +#ifndef NO_SYS +#define NO_SYS 0 +#endif + +/** + * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 + * Mainly for compatibility to old versions. + */ +#ifndef NO_SYS_NO_TIMERS +#define NO_SYS_NO_TIMERS 0 +#endif + +/** + * MEMCPY: override this if you have a faster implementation at hand than the + * one included in your C library + */ +#ifndef MEMCPY +#define MEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/** + * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a + * call to memcpy() if the length is known at compile time and is small. + */ +#ifndef SMEMCPY +#define SMEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#ifndef MEM_LIBC_MALLOC +#define MEM_LIBC_MALLOC 0 +#endif + +/** +* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. +* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution +* speed and usage from interrupts! +*/ +#ifndef MEMP_MEM_MALLOC +#define MEMP_MEM_MALLOC 0 +#endif + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> #define MEM_ALIGNMENT 4 + * 2 byte alignment -> #define MEM_ALIGNMENT 2 + */ +#ifndef MEM_ALIGNMENT +#define MEM_ALIGNMENT 1 +#endif + +/** + * MEM_SIZE: the size of the heap memory. If the application will send + * a lot of data that needs to be copied, this should be set high. + */ +#ifndef MEM_SIZE +#define MEM_SIZE 1600 +#endif + +/** + * MEMP_SEPARATE_POOLS: if defined to 1, each pool is placed in its own array. + * This can be used to individually change the location of each pool. + * Default is one big array for all pools + */ +#ifndef MEMP_SEPARATE_POOLS +#define MEMP_SEPARATE_POOLS 0 +#endif + +/** + * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable + * amount of bytes before and after each memp element in every pool and fills + * it with a prominent default value. + * MEMP_OVERFLOW_CHECK == 0 no checking + * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed + * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time + * memp_malloc() or memp_free() is called (useful but slow!) + */ +#ifndef MEMP_OVERFLOW_CHECK +#define MEMP_OVERFLOW_CHECK 0 +#endif + +/** + * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make + * sure that there are no cycles in the linked lists. + */ +#ifndef MEMP_SANITY_CHECK +#define MEMP_SANITY_CHECK 0 +#endif + +/** + * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set + * of memory pools of various sizes. When mem_malloc is called, an element of + * the smallest pool that can provide the length needed is returned. + * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. + */ +#ifndef MEM_USE_POOLS +#define MEM_USE_POOLS 0 +#endif + +/** + * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next + * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more + * reliable. */ +#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +#endif + +/** + * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h + * that defines additional pools beyond the "standard" ones required + * by lwIP. If you set this to 1, you must have lwippools.h in your + * inlude path somewhere. + */ +#ifndef MEMP_USE_CUSTOM_POOLS +#define MEMP_USE_CUSTOM_POOLS 0 +#endif + +/** + * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from + * interrupt context (or another context that doesn't allow waiting for a + * semaphore). + * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, + * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs + * with each loop so that mem_free can run. + * + * ATTENTION: As you can see from the above description, this leads to dis-/ + * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc + * can need longer. + * + * If you don't want that, at least for NO_SYS=0, you can still use the following + * functions to enqueue a deallocation call which then runs in the tcpip_thread + * context: + * - pbuf_free_callback(p); + * - mem_free_callback(m); + */ +#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 +#endif + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ +/** + * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). + * If the application sends a lot of data out of ROM (or other static memory), + * this should be set high. + */ +#ifndef MEMP_NUM_PBUF +#define MEMP_NUM_PBUF 16 +#endif + +/** + * MEMP_NUM_RAW_PCB: Number of raw connection PCBs + * (requires the LWIP_RAW option) + */ +#ifndef MEMP_NUM_RAW_PCB +#define MEMP_NUM_RAW_PCB 4 +#endif + +/** + * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + * per active UDP "connection". + * (requires the LWIP_UDP option) + */ +#ifndef MEMP_NUM_UDP_PCB +#define MEMP_NUM_UDP_PCB 4 +#endif + +/** + * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB +#define MEMP_NUM_TCP_PCB 5 +#endif + +/** + * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB_LISTEN +#define MEMP_NUM_TCP_PCB_LISTEN 8 +#endif + +/** + * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_SEG +#define MEMP_NUM_TCP_SEG 16 +#endif + +/** + * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for + * reassembly (whole packets, not fragments!) + */ +#ifndef MEMP_NUM_REASSDATA +#define MEMP_NUM_REASSDATA 5 +#endif + +/** + * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent + * (fragments, not whole packets!). + * This is only used with IP_FRAG_USES_STATIC_BUF==0 and + * LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 with DMA-enabled MACs + * where the packet is not yet sent when netif->output returns. + */ +#ifndef MEMP_NUM_FRAG_PBUF +#define MEMP_NUM_FRAG_PBUF 15 +#endif + +/** + * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing + * packets (pbufs) that are waiting for an ARP request (to resolve + * their destination address) to finish. + * (requires the ARP_QUEUEING option) + */ +#ifndef MEMP_NUM_ARP_QUEUE +#define MEMP_NUM_ARP_QUEUE 30 +#endif + +/** + * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces + * can be members et the same time (one per netif - allsystems group -, plus one + * per netif membership). + * (requires the LWIP_IGMP option) + */ +#ifndef MEMP_NUM_IGMP_GROUP +#define MEMP_NUM_IGMP_GROUP 8 +#endif + +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. + * (requires NO_SYS==0) + * The default number of timeouts is calculated here for all enabled modules. + * The formula expects settings to be either '0' or '1'. + */ +#ifndef MEMP_NUM_SYS_TIMEOUT +#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) +#endif + +/** + * MEMP_NUM_NETBUF: the number of struct netbufs. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETBUF +#define MEMP_NUM_NETBUF 2 +#endif + +/** + * MEMP_NUM_NETCONN: the number of struct netconns. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 4 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used + * for callback/timeout API communication. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_TCPIP_MSG_API 8 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used + * for incoming packets. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_INPKT +#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#endif + +/** + * MEMP_NUM_SNMP_NODE: the number of leafs in the SNMP tree. + */ +#ifndef MEMP_NUM_SNMP_NODE +#define MEMP_NUM_SNMP_NODE 50 +#endif + +/** + * MEMP_NUM_SNMP_ROOTNODE: the number of branches in the SNMP tree. + * Every branch has one leaf (MEMP_NUM_SNMP_NODE) at least! + */ +#ifndef MEMP_NUM_SNMP_ROOTNODE +#define MEMP_NUM_SNMP_ROOTNODE 30 +#endif + +/** + * MEMP_NUM_SNMP_VARBIND: the number of concurrent requests (does not have to + * be changed normally) - 2 of these are used per request (1 for input, + * 1 for output) + */ +#ifndef MEMP_NUM_SNMP_VARBIND +#define MEMP_NUM_SNMP_VARBIND 2 +#endif + +/** + * MEMP_NUM_SNMP_VALUE: the number of OID or values concurrently used + * (does not have to be changed normally) - 3 of these are used per request + * (1 for the value read and 2 for OIDs - input and output) + */ +#ifndef MEMP_NUM_SNMP_VALUE +#define MEMP_NUM_SNMP_VALUE 3 +#endif + +/** + * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls + * (before freeing the corresponding memory using lwip_freeaddrinfo()). + */ +#ifndef MEMP_NUM_NETDB +#define MEMP_NUM_NETDB 1 +#endif + +/** + * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list + * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. + */ +#ifndef MEMP_NUM_LOCALHOSTLIST +#define MEMP_NUM_LOCALHOSTLIST 1 +#endif + +/** + * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE + * interfaces (only used with PPPOE_SUPPORT==1) + */ +#ifndef MEMP_NUM_PPPOE_INTERFACES +#define MEMP_NUM_PPPOE_INTERFACES 1 +#endif + +/** + * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. + */ +#ifndef PBUF_POOL_SIZE +#define PBUF_POOL_SIZE 16 +#endif + +/* + --------------------------------- + ---------- ARP options ---------- + --------------------------------- +*/ +/** + * LWIP_ARP==1: Enable ARP functionality. + */ +#ifndef LWIP_ARP +#define LWIP_ARP 1 +#endif + +/** + * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. + */ +#ifndef ARP_TABLE_SIZE +#define ARP_TABLE_SIZE 10 +#endif + +/** + * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address + * resolution. By default, only the most recent packet is queued per IP address. + * This is sufficient for most protocols and mainly reduces TCP connection + * startup time. Set this to 1 if you know your application sends more than one + * packet in a row to an IP address that is not in the ARP cache. + */ +#ifndef ARP_QUEUEING +#define ARP_QUEUEING 0 +#endif + +/** + * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be + * updated with the source MAC and IP addresses supplied in the packet. + * You may want to disable this if you do not trust LAN peers to have the + * correct addresses, or as a limited approach to attempt to handle + * spoofing. If disabled, lwIP will need to make a new ARP request if + * the peer is not already in the ARP table, adding a little latency. + * The peer *is* in the ARP table if it requested our address before. + * Also notice that this slows down input processing of every IP packet! + */ +#ifndef ETHARP_TRUST_IP_MAC +#define ETHARP_TRUST_IP_MAC 0 +#endif + +/** + * ETHARP_SUPPORT_VLAN==1: support receiving ethernet packets with VLAN header. + * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. + * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. + * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. + * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan) + * that returns 1 to accept a packet or 0 to drop a packet. + */ +#ifndef ETHARP_SUPPORT_VLAN +#define ETHARP_SUPPORT_VLAN 0 +#endif + +/** LWIP_ETHERNET==1: enable ethernet support for PPPoE even though ARP + * might be disabled + */ +#ifndef LWIP_ETHERNET +#define LWIP_ETHERNET (LWIP_ARP || PPPOE_SUPPORT) +#endif + +/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure + * alignment of payload after that header. Since the header is 14 bytes long, + * without this padding e.g. addresses in the IP header will not be aligned + * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. + */ +#ifndef ETH_PAD_SIZE +#define ETH_PAD_SIZE 0 +#endif + +/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table + * entries (using etharp_add_static_entry/etharp_remove_static_entry). + */ +#ifndef ETHARP_SUPPORT_STATIC_ENTRIES +#define ETHARP_SUPPORT_STATIC_ENTRIES 0 +#endif + + +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ +/** + * IP_FORWARD==1: Enables the ability to forward IP packets across network + * interfaces. If you are going to run lwIP on a device with only one network + * interface, define this to 0. + */ +#ifndef IP_FORWARD +#define IP_FORWARD 0 +#endif + +/** + * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. + * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. + * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). + */ +#ifndef IP_OPTIONS_ALLOWED +#define IP_OPTIONS_ALLOWED 1 +#endif + +/** + * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that + * this option does not affect outgoing packet sizes, which can be controlled + * via IP_FRAG. + */ +#ifndef IP_REASSEMBLY +#define IP_REASSEMBLY 1 +#endif + +/** + * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note + * that this option does not affect incoming packet sizes, which can be + * controlled via IP_REASSEMBLY. + */ +#ifndef IP_FRAG +#define IP_FRAG 1 +#endif + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#ifndef IP_REASS_MAXAGE +#define IP_REASS_MAXAGE 3 +#endif + +/** + * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. + * Since the received pbufs are enqueued, be sure to configure + * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive + * packets even if the maximum amount of fragments is enqueued for reassembly! + */ +#ifndef IP_REASS_MAX_PBUFS +#define IP_REASS_MAX_PBUFS 10 +#endif + +/** + * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP + * fragmentation. Otherwise pbufs are allocated and reference the original + * packet data to be fragmented (or with LWIP_NETIF_TX_SINGLE_PBUF==1, + * new PBUF_RAM pbufs are used for fragments). + * ATTENTION: IP_FRAG_USES_STATIC_BUF==1 may not be used for DMA-enabled MACs! + */ +#ifndef IP_FRAG_USES_STATIC_BUF +#define IP_FRAG_USES_STATIC_BUF 0 +#endif + +/** + * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer + * (requires IP_FRAG_USES_STATIC_BUF==1) + */ +#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU) +#define IP_FRAG_MAX_MTU 1500 +#endif + +/** + * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. + */ +#ifndef IP_DEFAULT_TTL +#define IP_DEFAULT_TTL 255 +#endif + +/** + * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast + * filter per pcb on udp and raw send operations. To enable broadcast filter + * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. + */ +#ifndef IP_SOF_BROADCAST +#define IP_SOF_BROADCAST 0 +#endif + +/** + * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast + * filter on recv operations. + */ +#ifndef IP_SOF_BROADCAST_RECV +#define IP_SOF_BROADCAST_RECV 0 +#endif + +/** + * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back + * out on the netif where it was received. This should only be used for + * wireless networks. + * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming + * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags! + */ +#ifndef IP_FORWARD_ALLOW_TX_ON_RX_NETIF +#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 +#endif + +/** + * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first + * local TCP/UDP pcb (default==0). This can prevent creating predictable port + * numbers after booting a device. + */ +#ifndef LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS +#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 0 +#endif + +/* + ---------------------------------- + ---------- ICMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_ICMP==1: Enable ICMP module inside the IP stack. + * Be careful, disable that make your product non-compliant to RFC1122 + */ +#ifndef LWIP_ICMP +#define LWIP_ICMP 1 +#endif + +/** + * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. + */ +#ifndef ICMP_TTL +#define ICMP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) + */ +#ifndef LWIP_BROADCAST_PING +#define LWIP_BROADCAST_PING 0 +#endif + +/** + * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) + */ +#ifndef LWIP_MULTICAST_PING +#define LWIP_MULTICAST_PING 0 +#endif + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef LWIP_RAW +#define LWIP_RAW 1 +#endif + +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef RAW_TTL +#define RAW_TTL (IP_DEFAULT_TTL) +#endif + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#ifndef LWIP_DHCP +#define LWIP_DHCP 0 +#endif + +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#ifndef DHCP_DOES_ARP_CHECK +#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) +#endif + +/* + ------------------------------------ + ---------- AUTOIP options ---------- + ------------------------------------ +*/ +/** + * LWIP_AUTOIP==1: Enable AUTOIP module. + */ +#ifndef LWIP_AUTOIP +#define LWIP_AUTOIP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on + * the same interface at the same time. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP +#define LWIP_DHCP_AUTOIP_COOP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes + * that should be sent before falling back on AUTOIP. This can be set + * as low as 1 to get an AutoIP address very quickly, but you should + * be prepared to handle a changing IP address when DHCP overrides + * AutoIP. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES +#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 +#endif + +/* + ---------------------------------- + ---------- SNMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP + * transport. + */ +#ifndef LWIP_SNMP +#define LWIP_SNMP 0 +#endif + +/** + * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will + * allow. At least one request buffer is required. + * Does not have to be changed unless external MIBs answer request asynchronously + */ +#ifndef SNMP_CONCURRENT_REQUESTS +#define SNMP_CONCURRENT_REQUESTS 1 +#endif + +/** + * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap + * destination is required + */ +#ifndef SNMP_TRAP_DESTINATIONS +#define SNMP_TRAP_DESTINATIONS 1 +#endif + +/** + * SNMP_PRIVATE_MIB: + * When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. + */ +#ifndef SNMP_PRIVATE_MIB +#define SNMP_PRIVATE_MIB 0 +#endif + +/** + * Only allow SNMP write actions that are 'safe' (e.g. disabeling netifs is not + * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). + * Unsafe requests are disabled by default! + */ +#ifndef SNMP_SAFE_REQUESTS +#define SNMP_SAFE_REQUESTS 1 +#endif + +/** + * The maximum length of strings used. This affects the size of + * MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_OCTET_STRING_LEN +#define SNMP_MAX_OCTET_STRING_LEN 127 +#endif + +/** + * The maximum depth of the SNMP tree. + * With private MIBs enabled, this depends on your MIB! + * This affects the size of MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_TREE_DEPTH +#define SNMP_MAX_TREE_DEPTH 15 +#endif + +/** + * The size of the MEMP_SNMP_VALUE elements, normally calculated from + * SNMP_MAX_OCTET_STRING_LEN and SNMP_MAX_TREE_DEPTH. + */ +#ifndef SNMP_MAX_VALUE_SIZE +#define SNMP_MAX_VALUE_SIZE LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN)+1, sizeof(s32_t)*(SNMP_MAX_TREE_DEPTH)) +#endif + +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#ifndef LWIP_IGMP +#define LWIP_IGMP 0 +#endif + +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#ifndef LWIP_DNS +#define LWIP_DNS 0 +#endif + +/** DNS maximum number of entries to maintain locally. */ +#ifndef DNS_TABLE_SIZE +#define DNS_TABLE_SIZE 4 +#endif + +/** DNS maximum host name length supported in the name table. */ +#ifndef DNS_MAX_NAME_LENGTH +#define DNS_MAX_NAME_LENGTH 256 +#endif + +/** The maximum of DNS servers */ +#ifndef DNS_MAX_SERVERS +#define DNS_MAX_SERVERS 2 +#endif + +/** DNS do a name checking between the query and the response. */ +#ifndef DNS_DOES_NAME_CHECK +#define DNS_DOES_NAME_CHECK 1 +#endif + +/** DNS message max. size. Default value is RFC compliant. */ +#ifndef DNS_MSG_SIZE +#define DNS_MSG_SIZE 512 +#endif + +/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, + * you have to define + * #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}} + * (an array of structs name/address, where address is an u32_t in network + * byte order). + * + * Instead, you can also use an external function: + * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name) + * that returns the IP address or INADDR_NONE if not found. + */ +#ifndef DNS_LOCAL_HOSTLIST +#define DNS_LOCAL_HOSTLIST 0 +#endif /* DNS_LOCAL_HOSTLIST */ + +/** If this is turned on, the local host-list can be dynamically changed + * at runtime. */ +#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +/** + * LWIP_UDP==1: Turn on UDP. + */ +#ifndef LWIP_UDP +#define LWIP_UDP 1 +#endif + +#ifndef LWIP_SO_LINGER +#define LWIP_SO_LINGER 1 +#endif + +/** + * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) + */ +#ifndef LWIP_UDPLITE +#define LWIP_UDPLITE 0 +#endif + +/** + * UDP_TTL: Default Time-To-Live value. + */ +#ifndef UDP_TTL +#define UDP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. + */ +#ifndef LWIP_NETBUF_RECVINFO +#define LWIP_NETBUF_RECVINFO 0 +#endif + +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +/** + * LWIP_TCP==1: Turn on TCP. + */ +#ifndef LWIP_TCP +#define LWIP_TCP 1 +#endif + +/** + * TCP_TTL: Default Time-To-Live value. + */ +#ifndef TCP_TTL +#define TCP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * TCP_WND: The size of a TCP window. This must be at least + * (2 * TCP_MSS) for things to work well + */ +#ifndef TCP_WND +#define TCP_WND (4 * TCP_MSS) +#endif + +/** + * TCP_MAXRTX: Maximum number of retransmissions of data segments. + */ +#ifndef TCP_MAXRTX +#define TCP_MAXRTX 12 +#endif + +/** + * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. + */ +#ifndef TCP_SYNMAXRTX +#define TCP_SYNMAXRTX 6 +#endif + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#ifndef TCP_QUEUE_OOSEQ +#define TCP_QUEUE_OOSEQ (LWIP_TCP) +#endif + +/** + * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, + * you might want to increase this.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. + */ +#ifndef TCP_MSS +#define TCP_MSS 536 +#endif + +/** + * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really + * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which + * reflects the available reassembly buffer size at the remote host) and the + * largest size permitted by the IP layer" (RFC 1122) + * Setting this to 1 enables code that checks TCP_MSS against the MTU of the + * netif used for a connection and limits the MSS if it would be too big otherwise. + */ +#ifndef TCP_CALCULATE_EFF_SEND_MSS +#define TCP_CALCULATE_EFF_SEND_MSS 1 +#endif + + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + * To achieve good performance, this should be at least 2 * TCP_MSS. + */ +#ifndef TCP_SND_BUF +#define TCP_SND_BUF (2 * TCP_MSS) +#endif + +/** + * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. + */ +#ifndef TCP_SND_QUEUELEN +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) +#endif + +/** + * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than + * TCP_SND_BUF. It is the amount of space which must be available in the + * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). + */ +#ifndef TCP_SNDLOWAT +#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) +#endif + +/** + * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less + * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below + * this number, select returns writable (combined with TCP_SNDLOWAT). + */ +#ifndef TCP_SNDQUEUELOWAT +#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) +#endif + +/** + * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. + */ +#ifndef TCP_OOSEQ_MAX_BYTES +#define TCP_OOSEQ_MAX_BYTES 0 +#endif + +/** + * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. + */ +#ifndef TCP_OOSEQ_MAX_PBUFS +#define TCP_OOSEQ_MAX_PBUFS 0 +#endif + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#ifndef TCP_LISTEN_BACKLOG +#define TCP_LISTEN_BACKLOG 0 +#endif + +/** + * The maximum allowed backlog for TCP listen netconns. + * This backlog is used unless another is explicitly specified. + * 0xff is the maximum (u8_t). + */ +#ifndef TCP_DEFAULT_LISTEN_BACKLOG +#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +#endif + +/** + * TCP_OVERSIZE: The maximum number of bytes that tcp_write may + * allocate ahead of time in an attempt to create shorter pbuf chains + * for transmission. The meaningful range is 0 to TCP_MSS. Some + * suggested values are: + * + * 0: Disable oversized allocation. Each tcp_write() allocates a new + pbuf (old behaviour). + * 1: Allocate size-aligned pbufs with minimal excess. Use this if your + * scatter-gather DMA requires aligned fragments. + * 128: Limit the pbuf/memory overhead to 20%. + * TCP_MSS: Try to create unfragmented TCP packets. + * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. + */ +#ifndef TCP_OVERSIZE +#define TCP_OVERSIZE TCP_MSS +#endif + +/** + * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. + */ +#ifndef LWIP_TCP_TIMESTAMPS +#define LWIP_TCP_TIMESTAMPS 0 +#endif + +/** + * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an + * explicit window update + */ +#ifndef TCP_WND_UPDATE_THRESHOLD +#define TCP_WND_UPDATE_THRESHOLD (TCP_WND / 4) +#endif + +/** + * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. + * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all + * events (accept, sent, etc) that happen in the system. + * LWIP_CALLBACK_API==1: The PCB callback function is called directly + * for the event. This is the default. + */ +#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) +#define LWIP_EVENT_API 0 +#define LWIP_CALLBACK_API 1 +#endif + + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ +/** + * PBUF_LINK_HLEN: the number of bytes that should be allocated for a + * link level header. The default is 14, the standard value for + * Ethernet. + */ +#ifndef PBUF_LINK_HLEN +#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) +#endif + +/** + * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is + * designed to accomodate single full size TCP frame in one pbuf, including + * TCP_MSS, IP header, and link header. + */ +#ifndef PBUF_POOL_BUFSIZE +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN) +#endif + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 0 +#endif + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#ifndef LWIP_NETIF_API +#define LWIP_NETIF_API 0 +#endif + +/** + * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface + * changes its up/down status (i.e., due to DHCP IP acquistion) + */ +#ifndef LWIP_NETIF_STATUS_CALLBACK +#define LWIP_NETIF_STATUS_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface + * whenever the link changes (i.e., link down) + */ +#ifndef LWIP_NETIF_LINK_CALLBACK +#define LWIP_NETIF_LINK_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called + * when a netif has been removed + */ +#ifndef LWIP_NETIF_REMOVE_CALLBACK +#define LWIP_NETIF_REMOVE_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table + * indices) in struct netif. TCP and UDP can make use of this to prevent + * scanning the ARP table for every sent packet. While this is faster for big + * ARP tables or many concurrent connections, it might be counterproductive + * if you have a tiny ARP table or if there never are concurrent connections. + */ +#ifndef LWIP_NETIF_HWADDRHINT +#define LWIP_NETIF_HWADDRHINT 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP + * address equal to the netif IP address, looping them back up the stack. + */ +#ifndef LWIP_NETIF_LOOPBACK +#define LWIP_NETIF_LOOPBACK 0 +#endif + +/** + * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback + * sending for each netif (0 = disabled) + */ +#ifndef LWIP_LOOPBACK_MAX_PBUFS +#define LWIP_LOOPBACK_MAX_PBUFS 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in + * the system, as netifs must change how they behave depending on this setting + * for the LWIP_NETIF_LOOPBACK option to work. + * Setting this is needed to avoid reentering non-reentrant functions like + * tcp_input(). + * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a + * multithreaded environment like tcpip.c. In this case, netif->input() + * is called directly. + * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. + * The packets are put on a list and netif_poll() must be called in + * the main application loop. + */ +#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING +#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) +#endif + +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * to be sent into one single pbuf. This is for compatibility with DMA-enabled + * MACs that do not support scatter-gather. + * Beware that this might involve CPU-memcpy before transmitting that would not + * be needed without this flag! Use this only if you need to! + * + * @todo: TCP and IP-frag do not work with this, yet: + */ +#ifndef LWIP_NETIF_TX_SINGLE_PBUF +#define LWIP_NETIF_TX_SINGLE_PBUF 0 +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + +/* + ------------------------------------ + ---------- LOOPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c + */ +#ifndef LWIP_HAVE_LOOPIF +#define LWIP_HAVE_LOOPIF 0 +#endif + +/* + ------------------------------------ + ---------- SLIPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c + */ +#ifndef LWIP_HAVE_SLIPIF +#define LWIP_HAVE_SLIPIF 0 +#endif + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. + */ +#ifndef TCPIP_THREAD_NAME +#define TCPIP_THREAD_NAME "tcpip_thread" +#endif + +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_STACKSIZE +#define TCPIP_THREAD_STACKSIZE 0 +#endif + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_PRIO +#define TCPIP_THREAD_PRIO 1 +#endif + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#ifndef TCPIP_MBOX_SIZE +#define TCPIP_MBOX_SIZE 0 +#endif + +/** + * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. + */ +#ifndef SLIPIF_THREAD_NAME +#define SLIPIF_THREAD_NAME "slipif_loop" +#endif + +/** + * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_STACKSIZE +#define SLIPIF_THREAD_STACKSIZE 0 +#endif + +/** + * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_PRIO +#define SLIPIF_THREAD_PRIO 1 +#endif + +/** + * PPP_THREAD_NAME: The name assigned to the pppInputThread. + */ +#ifndef PPP_THREAD_NAME +#define PPP_THREAD_NAME "pppInputThread" +#endif + +/** + * PPP_THREAD_STACKSIZE: The stack size used by the pppInputThread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_STACKSIZE +#define PPP_THREAD_STACKSIZE 0 +#endif + +/** + * PPP_THREAD_PRIO: The priority assigned to the pppInputThread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_PRIO +#define PPP_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. + */ +#ifndef DEFAULT_THREAD_NAME +#define DEFAULT_THREAD_NAME "lwIP" +#endif + +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_STACKSIZE +#define DEFAULT_THREAD_STACKSIZE 0 +#endif + +/** + * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_PRIO +#define DEFAULT_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_RAW_RECVMBOX_SIZE +#define DEFAULT_RAW_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_UDP_RECVMBOX_SIZE +#define DEFAULT_UDP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_TCP_RECVMBOX_SIZE +#define DEFAULT_TCP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#ifndef DEFAULT_ACCEPTMBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE 0 +#endif + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** + * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING +#define LWIP_TCPIP_CORE_LOCKING 0 +#endif + +/** + * LWIP_TCPIP_CORE_LOCKING_INPUT: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT +#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 +#endif + +/** + * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) + */ +#ifndef LWIP_NETCONN +#define LWIP_NETCONN 1 +#endif + +/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout tod create + * timers running in tcpip_thread from another thread. + */ +#ifndef LWIP_TCPIP_TIMEOUT +#define LWIP_TCPIP_TIMEOUT 1 +#endif + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#ifndef LWIP_SOCKET +#define LWIP_SOCKET 1 +#endif + +/** + * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names. + * (only used if you use sockets.c) + */ +#ifndef LWIP_COMPAT_SOCKETS +#define LWIP_COMPAT_SOCKETS 1 +#endif + +/** + * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. + * Disable this option if you use a POSIX operating system that uses the same + * names (read, write & close). (only used if you use sockets.c) + */ +#ifndef LWIP_POSIX_SOCKETS_IO_NAMES +#define LWIP_POSIX_SOCKETS_IO_NAMES 1 +#endif + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#ifndef LWIP_TCP_KEEPALIVE +#define LWIP_TCP_KEEPALIVE 0 +#endif + +/** + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#ifndef LWIP_SO_SNDTIMEO +#define LWIP_SO_SNDTIMEO 0 +#endif + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. + */ +#ifndef LWIP_SO_RCVTIMEO +#define LWIP_SO_RCVTIMEO 0 +#endif + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#ifndef LWIP_SO_RCVBUF +#define LWIP_SO_RCVBUF 0 +#endif + +/** + * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. + */ +#ifndef RECV_BUFSIZE_DEFAULT +#define RECV_BUFSIZE_DEFAULT INT_MAX +#endif + +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#ifndef SO_REUSE +#define SO_REUSE 0 +#endif + +/** + * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets + * to all local matches if SO_REUSEADDR is turned on. + * WARNING: Adds a memcpy for every packet if passing to more than one pcb! + */ +#ifndef SO_REUSE_RXTOALL +#define SO_REUSE_RXTOALL 0 +#endif + +/** + * LWIP_FIONREAD_LINUXMODE==0 (default): ioctl/FIONREAD returns the amount of + * pending data in the network buffer. This is the way windows does it. It's + * the default for lwIP since it is smaller. + * LWIP_FIONREAD_LINUXMODE==1: ioctl/FIONREAD returns the size of the next + * pending datagram in bytes. This is the way linux does it. This code is only + * here for compatibility. + */ +#ifndef LWIP_FIONREAD_LINUXMODE +#define LWIP_FIONREAD_LINUXMODE 0 +#endif + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#ifndef LWIP_STATS +#define LWIP_STATS 1 +#endif + +#if LWIP_STATS + +/** + * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. + */ +#ifndef LWIP_STATS_DISPLAY +#define LWIP_STATS_DISPLAY 0 +#endif + +/** + * LINK_STATS==1: Enable link stats. + */ +#ifndef LINK_STATS +#define LINK_STATS 1 +#endif + +/** + * ETHARP_STATS==1: Enable etharp stats. + */ +#ifndef ETHARP_STATS +#define ETHARP_STATS (LWIP_ARP) +#endif + +/** + * IP_STATS==1: Enable IP stats. + */ +#ifndef IP_STATS +#define IP_STATS 1 +#endif + +/** + * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is + * on if using either frag or reass. + */ +#ifndef IPFRAG_STATS +#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) +#endif + +/** + * ICMP_STATS==1: Enable ICMP stats. + */ +#ifndef ICMP_STATS +#define ICMP_STATS 1 +#endif + +/** + * IGMP_STATS==1: Enable IGMP stats. + */ +#ifndef IGMP_STATS +#define IGMP_STATS (LWIP_IGMP) +#endif + +/** + * UDP_STATS==1: Enable UDP stats. Default is on if + * UDP enabled, otherwise off. + */ +#ifndef UDP_STATS +#define UDP_STATS (LWIP_UDP) +#endif + +/** + * TCP_STATS==1: Enable TCP stats. Default is on if TCP + * enabled, otherwise off. + */ +#ifndef TCP_STATS +#define TCP_STATS (LWIP_TCP) +#endif + +/** + * MEM_STATS==1: Enable mem.c stats. + */ +#ifndef MEM_STATS +#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) +#endif + +/** + * MEMP_STATS==1: Enable memp.c pool stats. + */ +#ifndef MEMP_STATS +#define MEMP_STATS (MEMP_MEM_MALLOC == 0) +#endif + +/** + * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). + */ +#ifndef SYS_STATS +#define SYS_STATS (NO_SYS == 0) +#endif + +/** + * IP6_STATS==1: Enable IPv6 stats. + */ +#ifndef IP6_STATS +#define IP6_STATS (LWIP_IPV6) +#endif + +/** + * ICMP6_STATS==1: Enable ICMP for IPv6 stats. + */ +#ifndef ICMP6_STATS +#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6) +#endif + +/** + * IP6_FRAG_STATS==1: Enable IPv6 fragmentation stats. + */ +#ifndef IP6_FRAG_STATS +#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS)) +#endif + +/** + * MLD6_STATS==1: Enable MLD for IPv6 stats. + */ +#ifndef MLD6_STATS +#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD) +#endif + +/** + * ND6_STATS==1: Enable Neighbor discovery for IPv6 stats. + */ +#ifndef ND6_STATS +#define ND6_STATS (LWIP_IPV6) +#endif + +#else + +#define LINK_STATS 0 +#define ETHARP_STATS 0 +#define IP_STATS 0 +#define IPFRAG_STATS 0 +#define ICMP_STATS 0 +#define IGMP_STATS 0 +#define UDP_STATS 0 +#define TCP_STATS 0 +#define MEM_STATS 0 +#define MEMP_STATS 0 +#define SYS_STATS 0 +#define LWIP_STATS_DISPLAY 0 +#define IP6_STATS 0 +#define ICMP6_STATS 0 +#define IP6_FRAG_STATS 0 +#define MLD6_STATS 0 +#define ND6_STATS 0 + +#endif /* LWIP_STATS */ + +/* + --------------------------------- + ---------- PPP options ---------- + --------------------------------- +*/ +/** + * PPP_SUPPORT==1: Enable PPP. + */ +#ifndef PPP_SUPPORT +#define PPP_SUPPORT 0 +#endif + +/** + * PPPOE_SUPPORT==1: Enable PPP Over Ethernet + */ +#ifndef PPPOE_SUPPORT +#define PPPOE_SUPPORT 0 +#endif + +/** + * PPPOS_SUPPORT==1: Enable PPP Over Serial + */ +#ifndef PPPOS_SUPPORT +#define PPPOS_SUPPORT PPP_SUPPORT +#endif + +#if PPP_SUPPORT + +/** + * NUM_PPP: Max PPP sessions. + */ +#ifndef NUM_PPP +#define NUM_PPP 1 +#endif + +/** + * PAP_SUPPORT==1: Support PAP. + */ +#ifndef PAP_SUPPORT +#define PAP_SUPPORT 0 +#endif + +/** + * CHAP_SUPPORT==1: Support CHAP. + */ +#ifndef CHAP_SUPPORT +#define CHAP_SUPPORT 0 +#endif + +/** + * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef MSCHAP_SUPPORT +#define MSCHAP_SUPPORT 0 +#endif + +/** + * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CBCP_SUPPORT +#define CBCP_SUPPORT 0 +#endif + +/** + * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CCP_SUPPORT +#define CCP_SUPPORT 0 +#endif + +/** + * VJ_SUPPORT==1: Support VJ header compression. + */ +#ifndef VJ_SUPPORT +#define VJ_SUPPORT 0 +#endif + +/** + * MD5_SUPPORT==1: Support MD5 (see also CHAP). + */ +#ifndef MD5_SUPPORT +#define MD5_SUPPORT 0 +#endif + +/* + * Timeouts + */ +#ifndef FSM_DEFTIMEOUT +#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef FSM_DEFMAXTERMREQS +#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXCONFREQS +#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXNAKLOOPS +#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ +#endif + +#ifndef UPAP_DEFTIMEOUT +#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ +#endif + +#ifndef UPAP_DEFREQTIME +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif + +#ifndef CHAP_DEFTIMEOUT +#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef CHAP_DEFTRANSMITS +#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ +#endif + +/* Interval in seconds between keepalive echo requests, 0 to disable. */ +#ifndef LCP_ECHOINTERVAL +#define LCP_ECHOINTERVAL 0 +#endif + +/* Number of unanswered echo requests before failure. */ +#ifndef LCP_MAXECHOFAILS +#define LCP_MAXECHOFAILS 3 +#endif + +/* Max Xmit idle time (in jiffies) before resend flag char. */ +#ifndef PPP_MAXIDLEFLAG +#define PPP_MAXIDLEFLAG 100 +#endif + +/* + * Packet sizes + * + * Note - lcp shouldn't be allowed to negotiate stuff outside these + * limits. See lcp.h in the pppd directory. + * (XXX - these constants should simply be shared by lcp.c instead + * of living in lcp.h) + */ +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#ifndef PPP_MAXMTU +/* #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) */ +#define PPP_MAXMTU 1500 /* Largest MTU we allow */ +#endif +#define PPP_MINMTU 64 +#define PPP_MRU 1500 /* default MRU = max length of info field */ +#define PPP_MAXMRU 1500 /* Largest MRU we allow */ +#ifndef PPP_DEFMRU +#define PPP_DEFMRU 296 /* Try for this */ +#endif +#define PPP_MINMRU 128 /* No MRUs below this */ + +#ifndef MAXNAMELEN +#define MAXNAMELEN 256 /* max length of hostname or name for auth */ +#endif +#ifndef MAXSECRETLEN +#define MAXSECRETLEN 256 /* max length of password or secret */ +#endif + +#endif /* PPP_SUPPORT */ + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ +/** + * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. + */ +#ifndef CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP 1 +#endif + +/** + * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. + */ +#ifndef CHECKSUM_GEN_UDP +#define CHECKSUM_GEN_UDP 1 +#endif + +/** + * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. + */ +#ifndef CHECKSUM_GEN_TCP +#define CHECKSUM_GEN_TCP 1 +#endif + +/** + * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets. + */ +#ifndef CHECKSUM_GEN_ICMP +#define CHECKSUM_GEN_ICMP 1 +#endif + +/** + * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. + */ +#ifndef CHECKSUM_CHECK_IP +#define CHECKSUM_CHECK_IP 1 +#endif + +/** + * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. + */ +#ifndef CHECKSUM_CHECK_UDP +#define CHECKSUM_CHECK_UDP 1 +#endif + +/** + * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. + */ +#ifndef CHECKSUM_CHECK_TCP +#define CHECKSUM_CHECK_TCP 1 +#endif + +/** + * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from + * application buffers to pbufs. + */ +#ifndef LWIP_CHECKSUM_ON_COPY +#define LWIP_CHECKSUM_ON_COPY 0 +#endif + +/* + --------------------------------------- + ---------- IPv6 options --------------- + --------------------------------------- +*/ +/** + * LWIP_IPV6==1: Enable IPv6 + */ +#ifndef LWIP_IPV6 +#define LWIP_IPV6 0 +#endif + +/** + * LWIP_IPV6_NUM_ADDRESSES: Number of IPv6 addresses per netif. + */ +#ifndef LWIP_IPV6_NUM_ADDRESSES +#define LWIP_IPV6_NUM_ADDRESSES 3 +#endif + +/** + * LWIP_IPV6_FORWARD==1: Forward IPv6 packets across netifs + */ +#ifndef LWIP_IPV6_FORWARD +#define LWIP_IPV6_FORWARD 0 +#endif + +/** + * LWIP_ICMP6==1: Enable ICMPv6 (mandatory per RFC) + */ +#ifndef LWIP_ICMP6 +#define LWIP_ICMP6 (LWIP_IPV6) +#endif + +/** + * LWIP_ICMP6_DATASIZE: bytes from original packet to send back in + * ICMPv6 error messages. + */ +#ifndef LWIP_ICMP6_DATASIZE +#define LWIP_ICMP6_DATASIZE 8 +#endif + +/** + * LWIP_ICMP6_HL: default hop limit for ICMPv6 messages + */ +#ifndef LWIP_ICMP6_HL +#define LWIP_ICMP6_HL 255 +#endif + +/** + * LWIP_ICMP6_CHECKSUM_CHECK==1: verify checksum on ICMPv6 packets + */ +#ifndef LWIP_ICMP6_CHECKSUM_CHECK +#define LWIP_ICMP6_CHECKSUM_CHECK 1 +#endif + +/** + * LWIP_IPV6_MLD==1: Enable multicast listener discovery protocol. + */ +#ifndef LWIP_IPV6_MLD +#define LWIP_IPV6_MLD (LWIP_IPV6) +#endif + +/** + * MEMP_NUM_MLD6_GROUP: Max number of IPv6 multicast that can be joined. + */ +#ifndef MEMP_NUM_MLD6_GROUP +#define MEMP_NUM_MLD6_GROUP 4 +#endif + +/** + * LWIP_IPV6_FRAG==1: Fragment outgoing IPv6 packets that are too big. + */ +#ifndef LWIP_IPV6_FRAG +#define LWIP_IPV6_FRAG 0 +#endif + +/** + * LWIP_IPV6_REASS==1: reassemble incoming IPv6 packets that fragmented + */ +#ifndef LWIP_IPV6_REASS +#define LWIP_IPV6_REASS (LWIP_IPV6) +#endif + +/** + * LWIP_ND6_QUEUEING==1: queue outgoing IPv6 packets while MAC address + * is being resolved. + */ +#ifndef LWIP_ND6_QUEUEING +#define LWIP_ND6_QUEUEING (LWIP_IPV6) +#endif + +/** + * MEMP_NUM_ND6_QUEUE: Max number of IPv6 packets to queue during MAC resolution. + */ +#ifndef MEMP_NUM_ND6_QUEUE +#define MEMP_NUM_ND6_QUEUE 20 +#endif + +/** + * LWIP_ND6_NUM_NEIGHBORS: Number of entries in IPv6 neighbor cache + */ +#ifndef LWIP_ND6_NUM_NEIGHBORS +#define LWIP_ND6_NUM_NEIGHBORS 10 +#endif + +/** + * LWIP_ND6_NUM_DESTINATIONS: number of entries in IPv6 destination cache + */ +#ifndef LWIP_ND6_NUM_DESTINATIONS +#define LWIP_ND6_NUM_DESTINATIONS 10 +#endif + +/** + * LWIP_ND6_NUM_PREFIXES: number of entries in IPv6 on-link prefixes cache + */ +#ifndef LWIP_ND6_NUM_PREFIXES +#define LWIP_ND6_NUM_PREFIXES 5 +#endif + +/** + * LWIP_ND6_NUM_ROUTERS: number of entries in IPv6 default router cache + */ +#ifndef LWIP_ND6_NUM_ROUTERS +#define LWIP_ND6_NUM_ROUTERS 3 +#endif + +/** + * LWIP_ND6_MAX_MULTICAST_SOLICIT: max number of multicast solicit messages to send + * (neighbor solicit and router solicit) + */ +#ifndef LWIP_ND6_MAX_MULTICAST_SOLICIT +#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3 +#endif + +/** + * LWIP_ND6_MAX_UNICAST_SOLICIT: max number of unicast neighbor solicitation messages + * to send during neighbor reachability detection. + */ +#ifndef LWIP_ND6_MAX_UNICAST_SOLICIT +#define LWIP_ND6_MAX_UNICAST_SOLICIT 3 +#endif + +/** + * Unused: See ND RFC (time in milliseconds). + */ +#ifndef LWIP_ND6_MAX_ANYCAST_DELAY_TIME +#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000 +#endif + +/** + * Unused: See ND RFC + */ +#ifndef LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT +#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3 +#endif + +/** + * LWIP_ND6_REACHABLE_TIME: default neighbor reachable time (in milliseconds). + * May be updated by router advertisement messages. + */ +#ifndef LWIP_ND6_REACHABLE_TIME +#define LWIP_ND6_REACHABLE_TIME 30000 +#endif + +/** + * LWIP_ND6_RETRANS_TIMER: default retransmission timer for solicitation messages + */ +#ifndef LWIP_ND6_RETRANS_TIMER +#define LWIP_ND6_RETRANS_TIMER 1000 +#endif + +/** + * LWIP_ND6_DELAY_FIRST_PROBE_TIME: Delay before first unicast neighbor solicitation + * message is sent, during neighbor reachability detection. + */ +#ifndef LWIP_ND6_DELAY_FIRST_PROBE_TIME +#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000 +#endif + +/** + * LWIP_ND6_ALLOW_RA_UPDATES==1: Allow Router Advertisement messages to update + * Reachable time and retransmission timers, and netif MTU. + */ +#ifndef LWIP_ND6_ALLOW_RA_UPDATES +#define LWIP_ND6_ALLOW_RA_UPDATES 1 +#endif + +/** + * LWIP_IPV6_SEND_ROUTER_SOLICIT==1: Send router solicitation messages during + * network startup. + */ +#ifndef LWIP_IPV6_SEND_ROUTER_SOLICIT +#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1 +#endif + +/** + * LWIP_ND6_TCP_REACHABILITY_HINTS==1: Allow TCP to provide Neighbor Discovery + * with reachability hints for connected destinations. This helps avoid sending + * unicast neighbor solicitation messages. + */ +#ifndef LWIP_ND6_TCP_REACHABILITY_HINTS +#define LWIP_ND6_TCP_REACHABILITY_HINTS 1 +#endif + +/** + * LWIP_IPV6_AUTOCONFIG==1: Enable stateless address autoconfiguration as per RFC 4862. + */ +#ifndef LWIP_IPV6_AUTOCONFIG +#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6) +#endif + +/** + * LWIP_IPV6_DUP_DETECT_ATTEMPTS: Number of duplicate address detection attempts. + */ +#ifndef LWIP_IPV6_DUP_DETECT_ATTEMPTS +#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1 +#endif + +/** + * LWIP_IPV6_DHCP6==1: enable DHCPv6 stateful address autoconfiguration. + */ +#ifndef LWIP_IPV6_DHCP6 +#define LWIP_IPV6_DHCP6 0 +#endif + +/* + --------------------------------------- + ---------- Hook options --------------- + --------------------------------------- +*/ + +/* Hooks are undefined by default, define them to a function if you need them. */ + +/** + * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): + * - called from ip_input() (IPv4) + * - pbuf: received struct pbuf passed to ip_input() + * - input_netif: struct netif on which the packet has been received + * Return values: + * - 0: Hook has not consumed the packet, packet is processed as normal + * - != 0: Hook has consumed the packet. + * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook + * (i.e. free it when done). + */ + +/** + * LWIP_HOOK_IP4_ROUTE(dest): + * - called from ip_route() (IPv4) + * - dest: destination IPv4 address + * Returns the destination netif or NULL if no destination netif is found. In + * that case, ip_route() continues as normal. + */ + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +/** + * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is + * compared against this value. If it is smaller, then debugging + * messages are written. + */ +#ifndef LWIP_DBG_MIN_LEVEL +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#endif + +/** + * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable + * debug messages of certain types. + */ +#ifndef LWIP_DBG_TYPES_ON +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#endif + +/** + * ETHARP_DEBUG: Enable debugging in etharp.c. + */ +#ifndef ETHARP_DEBUG +#define ETHARP_DEBUG LWIP_DBG_OFF +#endif + +/** + * NETIF_DEBUG: Enable debugging in netif.c. + */ +#ifndef NETIF_DEBUG +#define NETIF_DEBUG LWIP_DBG_OFF +#endif + +/** + * PBUF_DEBUG: Enable debugging in pbuf.c. + */ +#ifndef PBUF_DEBUG +#define PBUF_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_LIB_DEBUG: Enable debugging in api_lib.c. + */ +#ifndef API_LIB_DEBUG +#define API_LIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_MSG_DEBUG: Enable debugging in api_msg.c. + */ +#ifndef API_MSG_DEBUG +#define API_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SOCKETS_DEBUG: Enable debugging in sockets.c. + */ +#ifndef SOCKETS_DEBUG +#define SOCKETS_DEBUG LWIP_DBG_OFF +#endif + +/** + * ICMP_DEBUG: Enable debugging in icmp.c. + */ +#ifndef ICMP_DEBUG +#define ICMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IGMP_DEBUG: Enable debugging in igmp.c. + */ +#ifndef IGMP_DEBUG +#define IGMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * INET_DEBUG: Enable debugging in inet.c. + */ +#ifndef INET_DEBUG +#define INET_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_DEBUG: Enable debugging for IP. + */ +#ifndef IP_DEBUG +#define IP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. + */ +#ifndef IP_REASS_DEBUG +#define IP_REASS_DEBUG LWIP_DBG_OFF +#endif + +/** + * RAW_DEBUG: Enable debugging in raw.c. + */ +#ifndef RAW_DEBUG +#define RAW_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEM_DEBUG: Enable debugging in mem.c. + */ +#ifndef MEM_DEBUG +#define MEM_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEMP_DEBUG: Enable debugging in memp.c. + */ +#ifndef MEMP_DEBUG +#define MEMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SYS_DEBUG: Enable debugging in sys.c. + */ +#ifndef SYS_DEBUG +#define SYS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TIMERS_DEBUG: Enable debugging in timers.c. + */ +#ifndef TIMERS_DEBUG +#define TIMERS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_DEBUG: Enable debugging for TCP. + */ +#ifndef TCP_DEBUG +#define TCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. + */ +#ifndef TCP_INPUT_DEBUG +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. + */ +#ifndef TCP_FR_DEBUG +#define TCP_FR_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit + * timeout. + */ +#ifndef TCP_RTO_DEBUG +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. + */ +#ifndef TCP_CWND_DEBUG +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. + */ +#ifndef TCP_WND_DEBUG +#define TCP_WND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. + */ +#ifndef TCP_OUTPUT_DEBUG +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. + */ +#ifndef TCP_RST_DEBUG +#define TCP_RST_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. + */ +#ifndef TCP_QLEN_DEBUG +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#endif + +/** + * UDP_DEBUG: Enable debugging in UDP. + */ +#ifndef UDP_DEBUG +#define UDP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCPIP_DEBUG: Enable debugging in tcpip.c. + */ +#ifndef TCPIP_DEBUG +#define TCPIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * PPP_DEBUG: Enable debugging for PPP. + */ +#ifndef PPP_DEBUG +#define PPP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SLIP_DEBUG: Enable debugging in slipif.c. + */ +#ifndef SLIP_DEBUG +#define SLIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * DHCP_DEBUG: Enable debugging in dhcp.c. + */ +#ifndef DHCP_DEBUG +#define DHCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * AUTOIP_DEBUG: Enable debugging in autoip.c. + */ +#ifndef AUTOIP_DEBUG +#define AUTOIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MSG_DEBUG: Enable debugging for SNMP messages. + */ +#ifndef SNMP_MSG_DEBUG +#define SNMP_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. + */ +#ifndef SNMP_MIB_DEBUG +#define SNMP_MIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * DNS_DEBUG: Enable debugging for DNS. + */ +#ifndef DNS_DEBUG +#define DNS_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP6_DEBUG: Enable debugging for IPv6. + */ +#ifndef IP6_DEBUG +#define IP6_DEBUG LWIP_DBG_OFF +#endif + +#endif /* __LWIP_OPT_H__ */ diff --git a/include/lwip/lwip/pbuf.h b/include/lwip/lwip/pbuf.h index 1865f5c2..e8448c73 100644 --- a/include/lwip/lwip/pbuf.h +++ b/include/lwip/lwip/pbuf.h @@ -1,192 +1,192 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef __LWIP_PBUF_H__ -#define __LWIP_PBUF_H__ - -#include "lwip/opt.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Currently, the pbuf_custom code is only needed for one specific configuration - * of IP_FRAG */ -#define LWIP_SUPPORT_CUSTOM_PBUF (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) - -/* @todo: We need a mechanism to prevent wasting memory in every pbuf - (TCP vs. UDP, IPv4 vs. IPv6: UDP/IPv4 packets may waste up to 28 bytes) */ - -#define PBUF_TRANSPORT_HLEN 20 -#if LWIP_IPV6 -#define PBUF_IP_HLEN 40 -#else -#define PBUF_IP_HLEN 20 -#endif - -typedef enum { - PBUF_TRANSPORT, - PBUF_IP, - PBUF_LINK, - PBUF_RAW, - PBUF_MAC -} pbuf_layer; - -typedef enum { - PBUF_RAM, /* pbuf data is stored in RAM */ - PBUF_ROM, /* pbuf data is stored in ROM */ - PBUF_REF, /* pbuf comes from the pbuf pool */ - PBUF_POOL, /* pbuf payload refers to RAM */ -#ifdef EBUF_LWIP - PBUF_ESF_RX /* pbuf payload is from WLAN */ -#endif /* ESF_LWIP */ -} pbuf_type; - - -/** indicates this packet's data should be immediately passed to the application */ -#define PBUF_FLAG_PUSH 0x01U -/** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a - a pbuf differently */ -#define PBUF_FLAG_IS_CUSTOM 0x02U -/** indicates this pbuf is UDP multicast to be looped back */ -#define PBUF_FLAG_MCASTLOOP 0x04U -/** indicates this pbuf was received as link-level broadcast */ -#define PBUF_FLAG_LLBCAST 0x08U -/** indicates this pbuf was received as link-level multicast */ -#define PBUF_FLAG_LLMCAST 0x10U -/** indicates this pbuf includes a TCP FIN flag */ -#define PBUF_FLAG_TCP_FIN 0x20U - -struct pbuf { - /** next pbuf in singly linked pbuf chain */ - struct pbuf *next; - - /** pointer to the actual data in the buffer */ - void *payload; - - /** - * total length of this buffer and all next buffers in chain - * belonging to the same packet. - * - * For non-queue packet chains this is the invariant: - * p->tot_len == p->len + (p->next? p->next->tot_len: 0) - */ - u16_t tot_len; - - /** length of this buffer */ - u16_t len; - - /** pbuf_type as u8_t instead of enum to save space */ - u8_t /*pbuf_type*/ type; - - /** misc flags */ - u8_t flags; - - /** - * the reference count always equals the number of pointers - * that refer to this pbuf. This can be pointers from an application, - * the stack itself, or pbuf->next pointers from a chain. - */ - u16_t ref; - - /* add a pointer for esf_buf */ - void * eb; -}; - -#if LWIP_SUPPORT_CUSTOM_PBUF -/** Prototype for a function to free a custom pbuf */ -typedef void (*pbuf_free_custom_fn)(struct pbuf *p); - -/** A custom pbuf: like a pbuf, but following a function pointer to free it. */ -struct pbuf_custom { - /** The actual pbuf */ - struct pbuf pbuf; - /** This function is called when pbuf_free deallocates this pbuf(_custom) */ - pbuf_free_custom_fn custom_free_function; -}; -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - -#if LWIP_TCP && TCP_QUEUE_OOSEQ -/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ -#ifndef PBUF_POOL_FREE_OOSEQ -#define PBUF_POOL_FREE_OOSEQ 1 -#endif /* PBUF_POOL_FREE_OOSEQ */ -#if NO_SYS && PBUF_POOL_FREE_OOSEQ -extern volatile u8_t pbuf_free_ooseq_pending; -void pbuf_free_ooseq(void); -/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() - at regular intervals from main level to check if ooseq pbufs need to be - freed! */ -#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \ - /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \ - ooseq queued pbufs now */ \ - pbuf_free_ooseq(); }}while(0) -#endif /* NO_SYS && PBUF_POOL_FREE_OOSEQ*/ -#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ */ - -/* Initializes the pbuf module. This call is empty for now, but may not be in future. */ -#define pbuf_init() - -struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type); -#if LWIP_SUPPORT_CUSTOM_PBUF -struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, - struct pbuf_custom *p, void *payload_mem, - u16_t payload_mem_len); -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ -void pbuf_realloc(struct pbuf *p, u16_t size); -u8_t pbuf_header(struct pbuf *p, s16_t header_size); -void pbuf_ref(struct pbuf *p); -u8_t pbuf_free(struct pbuf *p); -u8_t pbuf_clen(struct pbuf *p); -void pbuf_cat(struct pbuf *head, struct pbuf *tail); -void pbuf_chain(struct pbuf *head, struct pbuf *tail); -struct pbuf *pbuf_dechain(struct pbuf *p); -err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from); -u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset); -err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len); -struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer); -#if LWIP_CHECKSUM_ON_COPY -err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, - u16_t len, u16_t *chksum); -#endif /* LWIP_CHECKSUM_ON_COPY */ - -u8_t pbuf_get_at(struct pbuf* p, u16_t offset); -u16_t pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n); -u16_t pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset); -u16_t pbuf_strstr(struct pbuf* p, const char* substr); - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_PBUF_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __LWIP_PBUF_H__ +#define __LWIP_PBUF_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Currently, the pbuf_custom code is only needed for one specific configuration + * of IP_FRAG */ +#define LWIP_SUPPORT_CUSTOM_PBUF (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) + +/* @todo: We need a mechanism to prevent wasting memory in every pbuf + (TCP vs. UDP, IPv4 vs. IPv6: UDP/IPv4 packets may waste up to 28 bytes) */ + +#define PBUF_TRANSPORT_HLEN 20 +#if LWIP_IPV6 +#define PBUF_IP_HLEN 40 +#else +#define PBUF_IP_HLEN 20 +#endif + +typedef enum { + PBUF_TRANSPORT, + PBUF_IP, + PBUF_LINK, + PBUF_RAW, + PBUF_MAC +} pbuf_layer; + +typedef enum { + PBUF_RAM, /* pbuf data is stored in RAM */ + PBUF_ROM, /* pbuf data is stored in ROM */ + PBUF_REF, /* pbuf comes from the pbuf pool */ + PBUF_POOL, /* pbuf payload refers to RAM */ +#ifdef EBUF_LWIP + PBUF_ESF_RX /* pbuf payload is from WLAN */ +#endif /* ESF_LWIP */ +} pbuf_type; + + +/** indicates this packet's data should be immediately passed to the application */ +#define PBUF_FLAG_PUSH 0x01U +/** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a + a pbuf differently */ +#define PBUF_FLAG_IS_CUSTOM 0x02U +/** indicates this pbuf is UDP multicast to be looped back */ +#define PBUF_FLAG_MCASTLOOP 0x04U +/** indicates this pbuf was received as link-level broadcast */ +#define PBUF_FLAG_LLBCAST 0x08U +/** indicates this pbuf was received as link-level multicast */ +#define PBUF_FLAG_LLMCAST 0x10U +/** indicates this pbuf includes a TCP FIN flag */ +#define PBUF_FLAG_TCP_FIN 0x20U + +struct pbuf { + /** next pbuf in singly linked pbuf chain */ + struct pbuf *next; + + /** pointer to the actual data in the buffer */ + void *payload; + + /** + * total length of this buffer and all next buffers in chain + * belonging to the same packet. + * + * For non-queue packet chains this is the invariant: + * p->tot_len == p->len + (p->next? p->next->tot_len: 0) + */ + u16_t tot_len; + + /** length of this buffer */ + u16_t len; + + /** pbuf_type as u8_t instead of enum to save space */ + u8_t /*pbuf_type*/ type; + + /** misc flags */ + u8_t flags; + + /** + * the reference count always equals the number of pointers + * that refer to this pbuf. This can be pointers from an application, + * the stack itself, or pbuf->next pointers from a chain. + */ + u16_t ref; + + /* add a pointer for esf_buf */ + void * eb; +}; + +#if LWIP_SUPPORT_CUSTOM_PBUF +/** Prototype for a function to free a custom pbuf */ +typedef void (*pbuf_free_custom_fn)(struct pbuf *p); + +/** A custom pbuf: like a pbuf, but following a function pointer to free it. */ +struct pbuf_custom { + /** The actual pbuf */ + struct pbuf pbuf; + /** This function is called when pbuf_free deallocates this pbuf(_custom) */ + pbuf_free_custom_fn custom_free_function; +}; +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + +#if LWIP_TCP && TCP_QUEUE_OOSEQ +/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ +#ifndef PBUF_POOL_FREE_OOSEQ +#define PBUF_POOL_FREE_OOSEQ 1 +#endif /* PBUF_POOL_FREE_OOSEQ */ +#if NO_SYS && PBUF_POOL_FREE_OOSEQ +extern volatile u8_t pbuf_free_ooseq_pending; +void pbuf_free_ooseq(void); +/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() + at regular intervals from main level to check if ooseq pbufs need to be + freed! */ +#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \ + /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \ + ooseq queued pbufs now */ \ + pbuf_free_ooseq(); }}while(0) +#endif /* NO_SYS && PBUF_POOL_FREE_OOSEQ*/ +#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ */ + +/* Initializes the pbuf module. This call is empty for now, but may not be in future. */ +#define pbuf_init() + +struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type); +#if LWIP_SUPPORT_CUSTOM_PBUF +struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, + struct pbuf_custom *p, void *payload_mem, + u16_t payload_mem_len); +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ +void pbuf_realloc(struct pbuf *p, u16_t size); +u8_t pbuf_header(struct pbuf *p, s16_t header_size); +void pbuf_ref(struct pbuf *p); +u8_t pbuf_free(struct pbuf *p); +u8_t pbuf_clen(struct pbuf *p); +void pbuf_cat(struct pbuf *head, struct pbuf *tail); +void pbuf_chain(struct pbuf *head, struct pbuf *tail); +struct pbuf *pbuf_dechain(struct pbuf *p); +err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from); +u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset); +err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len); +struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer); +#if LWIP_CHECKSUM_ON_COPY +err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, + u16_t len, u16_t *chksum); +#endif /* LWIP_CHECKSUM_ON_COPY */ + +u8_t pbuf_get_at(struct pbuf* p, u16_t offset); +u16_t pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n); +u16_t pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset); +u16_t pbuf_strstr(struct pbuf* p, const char* substr); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_PBUF_H__ */ diff --git a/include/lwip/lwip/raw.h b/include/lwip/lwip/raw.h index ba4edd94..f0c8ed47 100644 --- a/include/lwip/lwip/raw.h +++ b/include/lwip/lwip/raw.h @@ -1,131 +1,131 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_RAW_H__ -#define __LWIP_RAW_H__ - -#include "lwip/opt.h" - -#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/def.h" -#include "lwip/ip.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct raw_pcb; - -/** Function prototype for raw pcb receive callback functions. - * @param arg user supplied argument (raw_pcb.recv_arg) - * @param pcb the raw_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IP address from which the packet was received - * @return 1 if the packet was 'eaten' (aka. deleted), - * 0 if the packet lives on - * If returning 1, the callback is responsible for freeing the pbuf - * if it's not used any more. - */ -typedef u8_t (*raw_recv_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, - ip_addr_t *addr); - -#if LWIP_IPV6 -/** Function prototype for raw pcb IPv6 receive callback functions. - * @param arg user supplied argument (raw_pcb.recv_arg) - * @param pcb the raw_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IPv6 address from which the packet was received - * @return 1 if the packet was 'eaten' (aka. deleted), - * 0 if the packet lives on - * If returning 1, the callback is responsible for freeing the pbuf - * if it's not used any more. - */ -typedef u8_t (*raw_recv_ip6_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, - ip6_addr_t *addr); -#endif /* LWIP_IPV6 */ - -#if LWIP_IPV6 -#define RAW_PCB_RECV_IP6 raw_recv_ip6_fn ip6; -#else -#define RAW_PCB_RECV_IP6 -#endif /* LWIP_IPV6 */ - -struct raw_pcb { - /* Common members of all PCB types */ - IP_PCB; - - struct raw_pcb *next; - - u8_t protocol; - - /** receive callback function */ - union { - raw_recv_fn ip4; - RAW_PCB_RECV_IP6 - } recv; - /* user-supplied argument for the recv callback */ - void *recv_arg; -}; - -/* The following functions is the application layer interface to the - RAW code. */ -struct raw_pcb * raw_new (u8_t proto); -void raw_remove (struct raw_pcb *pcb); -err_t raw_bind (struct raw_pcb *pcb, ip_addr_t *ipaddr); -err_t raw_connect (struct raw_pcb *pcb, ip_addr_t *ipaddr); - -void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg); -err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr); -err_t raw_send (struct raw_pcb *pcb, struct pbuf *p); - -#if LWIP_IPV6 -struct raw_pcb * raw_new_ip6 (u8_t proto); -#define raw_bind_ip6(pcb, ip6addr) raw_bind(pcb, ip6_2_ip(ip6addr)) -#define raw_connect_ip6(pcb, ip6addr) raw_connect(pcb, ip6_2_ip(ip6addr)) -#define raw_recv_ip6(pcb, recv_ip6_fn, recv_arg) raw_recv(pcb, (raw_recv_fn)recv_ip6_fn, recv_arg) -#define raw_sendto_ip6(pcb, pbuf, ip6addr) raw_sendto(pcb, pbuf, ip6_2_ip(ip6addr)) -#endif /* LWIP_IPV6 */ - -/* The following functions are the lower layer interface to RAW. */ -u8_t raw_input (struct pbuf *p, struct netif *inp); -#define raw_init() /* Compatibility define, not init needed. */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_RAW */ - -#endif /* __LWIP_RAW_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_RAW_H__ +#define __LWIP_RAW_H__ + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/def.h" +#include "lwip/ip.h" +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct raw_pcb; + +/** Function prototype for raw pcb receive callback functions. + * @param arg user supplied argument (raw_pcb.recv_arg) + * @param pcb the raw_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IP address from which the packet was received + * @return 1 if the packet was 'eaten' (aka. deleted), + * 0 if the packet lives on + * If returning 1, the callback is responsible for freeing the pbuf + * if it's not used any more. + */ +typedef u8_t (*raw_recv_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, + ip_addr_t *addr); + +#if LWIP_IPV6 +/** Function prototype for raw pcb IPv6 receive callback functions. + * @param arg user supplied argument (raw_pcb.recv_arg) + * @param pcb the raw_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IPv6 address from which the packet was received + * @return 1 if the packet was 'eaten' (aka. deleted), + * 0 if the packet lives on + * If returning 1, the callback is responsible for freeing the pbuf + * if it's not used any more. + */ +typedef u8_t (*raw_recv_ip6_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, + ip6_addr_t *addr); +#endif /* LWIP_IPV6 */ + +#if LWIP_IPV6 +#define RAW_PCB_RECV_IP6 raw_recv_ip6_fn ip6; +#else +#define RAW_PCB_RECV_IP6 +#endif /* LWIP_IPV6 */ + +struct raw_pcb { + /* Common members of all PCB types */ + IP_PCB; + + struct raw_pcb *next; + + u8_t protocol; + + /** receive callback function */ + union { + raw_recv_fn ip4; + RAW_PCB_RECV_IP6 + } recv; + /* user-supplied argument for the recv callback */ + void *recv_arg; +}; + +/* The following functions is the application layer interface to the + RAW code. */ +struct raw_pcb * raw_new (u8_t proto); +void raw_remove (struct raw_pcb *pcb); +err_t raw_bind (struct raw_pcb *pcb, ip_addr_t *ipaddr); +err_t raw_connect (struct raw_pcb *pcb, ip_addr_t *ipaddr); + +void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg); +err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr); +err_t raw_send (struct raw_pcb *pcb, struct pbuf *p); + +#if LWIP_IPV6 +struct raw_pcb * raw_new_ip6 (u8_t proto); +#define raw_bind_ip6(pcb, ip6addr) raw_bind(pcb, ip6_2_ip(ip6addr)) +#define raw_connect_ip6(pcb, ip6addr) raw_connect(pcb, ip6_2_ip(ip6addr)) +#define raw_recv_ip6(pcb, recv_ip6_fn, recv_arg) raw_recv(pcb, (raw_recv_fn)recv_ip6_fn, recv_arg) +#define raw_sendto_ip6(pcb, pbuf, ip6addr) raw_sendto(pcb, pbuf, ip6_2_ip(ip6addr)) +#endif /* LWIP_IPV6 */ + +/* The following functions are the lower layer interface to RAW. */ +u8_t raw_input (struct pbuf *p, struct netif *inp); +#define raw_init() /* Compatibility define, not init needed. */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_RAW */ + +#endif /* __LWIP_RAW_H__ */ diff --git a/include/lwip/lwip/sio.h b/include/lwip/lwip/sio.h index 39d778b4..28ae2f22 100644 --- a/include/lwip/lwip/sio.h +++ b/include/lwip/lwip/sio.h @@ -1,141 +1,141 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - */ - -/* - * This is the interface to the platform specific serial IO module - * It needs to be implemented by those platforms which need SLIP or PPP - */ - -#ifndef __SIO_H__ -#define __SIO_H__ - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* If you want to define sio_fd_t elsewhere or differently, - define this in your cc.h file. */ -#ifndef __sio_fd_t_defined -typedef void * sio_fd_t; -#endif - -/* The following functions can be defined to something else in your cc.h file - or be implemented in your custom sio.c file. */ - -#ifndef sio_open -/** - * Opens a serial device for communication. - * - * @param devnum device number - * @return handle to serial device if successful, NULL otherwise - */ -sio_fd_t sio_open(u8_t devnum); -#endif - -#ifndef sio_send -/** - * Sends a single character to the serial device. - * - * @param c character to send - * @param fd serial device handle - * - * @note This function will block until the character can be sent. - */ -void sio_send(u8_t c, sio_fd_t fd); -#endif - -#ifndef sio_recv -/** - * Receives a single character from the serial device. - * - * @param fd serial device handle - * - * @note This function will block until a character is received. - */ -u8_t sio_recv(sio_fd_t fd); -#endif - -#ifndef sio_read -/** - * Reads from the serial device. - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - may be 0 if aborted by sio_read_abort - * - * @note This function will block until data can be received. The blocking - * can be cancelled by calling sio_read_abort(). - */ -u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_tryread -/** - * Tries to read from the serial device. Same as sio_read but returns - * immediately if no data is available and never blocks. - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - */ -u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_write -/** - * Writes to the serial device. - * - * @param fd serial device handle - * @param data pointer to data to send - * @param len length (in bytes) of data to send - * @return number of bytes actually sent - * - * @note This function will block until all data can be sent. - */ -u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_read_abort -/** - * Aborts a blocking sio_read() call. - * - * @param fd serial device handle - */ -void sio_read_abort(sio_fd_t fd); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __SIO_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + */ + +/* + * This is the interface to the platform specific serial IO module + * It needs to be implemented by those platforms which need SLIP or PPP + */ + +#ifndef __SIO_H__ +#define __SIO_H__ + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If you want to define sio_fd_t elsewhere or differently, + define this in your cc.h file. */ +#ifndef __sio_fd_t_defined +typedef void * sio_fd_t; +#endif + +/* The following functions can be defined to something else in your cc.h file + or be implemented in your custom sio.c file. */ + +#ifndef sio_open +/** + * Opens a serial device for communication. + * + * @param devnum device number + * @return handle to serial device if successful, NULL otherwise + */ +sio_fd_t sio_open(u8_t devnum); +#endif + +#ifndef sio_send +/** + * Sends a single character to the serial device. + * + * @param c character to send + * @param fd serial device handle + * + * @note This function will block until the character can be sent. + */ +void sio_send(u8_t c, sio_fd_t fd); +#endif + +#ifndef sio_recv +/** + * Receives a single character from the serial device. + * + * @param fd serial device handle + * + * @note This function will block until a character is received. + */ +u8_t sio_recv(sio_fd_t fd); +#endif + +#ifndef sio_read +/** + * Reads from the serial device. + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @return number of bytes actually received - may be 0 if aborted by sio_read_abort + * + * @note This function will block until data can be received. The blocking + * can be cancelled by calling sio_read_abort(). + */ +u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_tryread +/** + * Tries to read from the serial device. Same as sio_read but returns + * immediately if no data is available and never blocks. + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @return number of bytes actually received + */ +u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_write +/** + * Writes to the serial device. + * + * @param fd serial device handle + * @param data pointer to data to send + * @param len length (in bytes) of data to send + * @return number of bytes actually sent + * + * @note This function will block until all data can be sent. + */ +u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_read_abort +/** + * Aborts a blocking sio_read() call. + * + * @param fd serial device handle + */ +void sio_read_abort(sio_fd_t fd); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __SIO_H__ */ diff --git a/include/lwip/lwip/snmp.h b/include/lwip/lwip/snmp.h index 3548ba29..2ed043dd 100644 --- a/include/lwip/lwip/snmp.h +++ b/include/lwip/lwip/snmp.h @@ -1,367 +1,367 @@ -/* - * Copyright (c) 2001, 2002 Leon Woestenberg - * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Leon Woestenberg - * - */ -#ifndef __LWIP_SNMP_H__ -#define __LWIP_SNMP_H__ - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lwip/ip_addr.h" - -struct udp_pcb; -struct netif; - -/** - * @see RFC1213, "MIB-II, 6. Definitions" - */ -enum snmp_ifType { - snmp_ifType_other=1, /* none of the following */ - snmp_ifType_regular1822, - snmp_ifType_hdh1822, - snmp_ifType_ddn_x25, - snmp_ifType_rfc877_x25, - snmp_ifType_ethernet_csmacd, - snmp_ifType_iso88023_csmacd, - snmp_ifType_iso88024_tokenBus, - snmp_ifType_iso88025_tokenRing, - snmp_ifType_iso88026_man, - snmp_ifType_starLan, - snmp_ifType_proteon_10Mbit, - snmp_ifType_proteon_80Mbit, - snmp_ifType_hyperchannel, - snmp_ifType_fddi, - snmp_ifType_lapb, - snmp_ifType_sdlc, - snmp_ifType_ds1, /* T-1 */ - snmp_ifType_e1, /* european equiv. of T-1 */ - snmp_ifType_basicISDN, - snmp_ifType_primaryISDN, /* proprietary serial */ - snmp_ifType_propPointToPointSerial, - snmp_ifType_ppp, - snmp_ifType_softwareLoopback, - snmp_ifType_eon, /* CLNP over IP [11] */ - snmp_ifType_ethernet_3Mbit, - snmp_ifType_nsip, /* XNS over IP */ - snmp_ifType_slip, /* generic SLIP */ - snmp_ifType_ultra, /* ULTRA technologies */ - snmp_ifType_ds3, /* T-3 */ - snmp_ifType_sip, /* SMDS */ - snmp_ifType_frame_relay -}; - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -/** SNMP "sysuptime" Interval */ -#define SNMP_SYSUPTIME_INTERVAL 10 - -/** fixed maximum length for object identifier type */ -#define LWIP_SNMP_OBJ_ID_LEN 32 - -/** internal object identifier representation */ -struct snmp_obj_id -{ - u8_t len; - s32_t id[LWIP_SNMP_OBJ_ID_LEN]; -}; - -/* system */ -void snmp_set_sysdesr(u8_t* str, u8_t* len); -void snmp_set_sysobjid(struct snmp_obj_id *oid); -void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid); -void snmp_inc_sysuptime(void); -void snmp_add_sysuptime(u32_t value); -void snmp_get_sysuptime(u32_t *value); -void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen); -void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen); -void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen); - -/* network interface */ -void snmp_add_ifinoctets(struct netif *ni, u32_t value); -void snmp_inc_ifinucastpkts(struct netif *ni); -void snmp_inc_ifinnucastpkts(struct netif *ni); -void snmp_inc_ifindiscards(struct netif *ni); -void snmp_add_ifoutoctets(struct netif *ni, u32_t value); -void snmp_inc_ifoutucastpkts(struct netif *ni); -void snmp_inc_ifoutnucastpkts(struct netif *ni); -void snmp_inc_ifoutdiscards(struct netif *ni); -void snmp_inc_iflist(void); -void snmp_dec_iflist(void); - -/* ARP (for atTable and ipNetToMediaTable) */ -void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip); -void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip); - -/* IP */ -void snmp_inc_ipinreceives(void); -void snmp_inc_ipinhdrerrors(void); -void snmp_inc_ipinaddrerrors(void); -void snmp_inc_ipforwdatagrams(void); -void snmp_inc_ipinunknownprotos(void); -void snmp_inc_ipindiscards(void); -void snmp_inc_ipindelivers(void); -void snmp_inc_ipoutrequests(void); -void snmp_inc_ipoutdiscards(void); -void snmp_inc_ipoutnoroutes(void); -void snmp_inc_ipreasmreqds(void); -void snmp_inc_ipreasmoks(void); -void snmp_inc_ipreasmfails(void); -void snmp_inc_ipfragoks(void); -void snmp_inc_ipfragfails(void); -void snmp_inc_ipfragcreates(void); -void snmp_inc_iproutingdiscards(void); -void snmp_insert_ipaddridx_tree(struct netif *ni); -void snmp_delete_ipaddridx_tree(struct netif *ni); -void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni); -void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni); - -/* ICMP */ -void snmp_inc_icmpinmsgs(void); -void snmp_inc_icmpinerrors(void); -void snmp_inc_icmpindestunreachs(void); -void snmp_inc_icmpintimeexcds(void); -void snmp_inc_icmpinparmprobs(void); -void snmp_inc_icmpinsrcquenchs(void); -void snmp_inc_icmpinredirects(void); -void snmp_inc_icmpinechos(void); -void snmp_inc_icmpinechoreps(void); -void snmp_inc_icmpintimestamps(void); -void snmp_inc_icmpintimestampreps(void); -void snmp_inc_icmpinaddrmasks(void); -void snmp_inc_icmpinaddrmaskreps(void); -void snmp_inc_icmpoutmsgs(void); -void snmp_inc_icmpouterrors(void); -void snmp_inc_icmpoutdestunreachs(void); -void snmp_inc_icmpouttimeexcds(void); -void snmp_inc_icmpoutparmprobs(void); -void snmp_inc_icmpoutsrcquenchs(void); -void snmp_inc_icmpoutredirects(void); -void snmp_inc_icmpoutechos(void); -void snmp_inc_icmpoutechoreps(void); -void snmp_inc_icmpouttimestamps(void); -void snmp_inc_icmpouttimestampreps(void); -void snmp_inc_icmpoutaddrmasks(void); -void snmp_inc_icmpoutaddrmaskreps(void); - -/* TCP */ -void snmp_inc_tcpactiveopens(void); -void snmp_inc_tcppassiveopens(void); -void snmp_inc_tcpattemptfails(void); -void snmp_inc_tcpestabresets(void); -void snmp_inc_tcpinsegs(void); -void snmp_inc_tcpoutsegs(void); -void snmp_inc_tcpretranssegs(void); -void snmp_inc_tcpinerrs(void); -void snmp_inc_tcpoutrsts(void); - -/* UDP */ -void snmp_inc_udpindatagrams(void); -void snmp_inc_udpnoports(void); -void snmp_inc_udpinerrors(void); -void snmp_inc_udpoutdatagrams(void); -void snmp_insert_udpidx_tree(struct udp_pcb *pcb); -void snmp_delete_udpidx_tree(struct udp_pcb *pcb); - -/* SNMP */ -void snmp_inc_snmpinpkts(void); -void snmp_inc_snmpoutpkts(void); -void snmp_inc_snmpinbadversions(void); -void snmp_inc_snmpinbadcommunitynames(void); -void snmp_inc_snmpinbadcommunityuses(void); -void snmp_inc_snmpinasnparseerrs(void); -void snmp_inc_snmpintoobigs(void); -void snmp_inc_snmpinnosuchnames(void); -void snmp_inc_snmpinbadvalues(void); -void snmp_inc_snmpinreadonlys(void); -void snmp_inc_snmpingenerrs(void); -void snmp_add_snmpintotalreqvars(u8_t value); -void snmp_add_snmpintotalsetvars(u8_t value); -void snmp_inc_snmpingetrequests(void); -void snmp_inc_snmpingetnexts(void); -void snmp_inc_snmpinsetrequests(void); -void snmp_inc_snmpingetresponses(void); -void snmp_inc_snmpintraps(void); -void snmp_inc_snmpouttoobigs(void); -void snmp_inc_snmpoutnosuchnames(void); -void snmp_inc_snmpoutbadvalues(void); -void snmp_inc_snmpoutgenerrs(void); -void snmp_inc_snmpoutgetrequests(void); -void snmp_inc_snmpoutgetnexts(void); -void snmp_inc_snmpoutsetrequests(void); -void snmp_inc_snmpoutgetresponses(void); -void snmp_inc_snmpouttraps(void); -void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid); -void snmp_set_snmpenableauthentraps(u8_t *value); -void snmp_get_snmpenableauthentraps(u8_t *value); - -/* LWIP_SNMP support not available */ -/* define everything to be empty */ -#else - -/* system */ -#define snmp_set_sysdesr(str, len) -#define snmp_set_sysobjid(oid); -#define snmp_get_sysobjid_ptr(oid) -#define snmp_inc_sysuptime() -#define snmp_add_sysuptime(value) -#define snmp_get_sysuptime(value) -#define snmp_set_syscontact(ocstr, ocstrlen); -#define snmp_set_sysname(ocstr, ocstrlen); -#define snmp_set_syslocation(ocstr, ocstrlen); - -/* network interface */ -#define snmp_add_ifinoctets(ni,value) -#define snmp_inc_ifinucastpkts(ni) -#define snmp_inc_ifinnucastpkts(ni) -#define snmp_inc_ifindiscards(ni) -#define snmp_add_ifoutoctets(ni,value) -#define snmp_inc_ifoutucastpkts(ni) -#define snmp_inc_ifoutnucastpkts(ni) -#define snmp_inc_ifoutdiscards(ni) -#define snmp_inc_iflist() -#define snmp_dec_iflist() - -/* ARP */ -#define snmp_insert_arpidx_tree(ni,ip) -#define snmp_delete_arpidx_tree(ni,ip) - -/* IP */ -#define snmp_inc_ipinreceives() -#define snmp_inc_ipinhdrerrors() -#define snmp_inc_ipinaddrerrors() -#define snmp_inc_ipforwdatagrams() -#define snmp_inc_ipinunknownprotos() -#define snmp_inc_ipindiscards() -#define snmp_inc_ipindelivers() -#define snmp_inc_ipoutrequests() -#define snmp_inc_ipoutdiscards() -#define snmp_inc_ipoutnoroutes() -#define snmp_inc_ipreasmreqds() -#define snmp_inc_ipreasmoks() -#define snmp_inc_ipreasmfails() -#define snmp_inc_ipfragoks() -#define snmp_inc_ipfragfails() -#define snmp_inc_ipfragcreates() -#define snmp_inc_iproutingdiscards() -#define snmp_insert_ipaddridx_tree(ni) -#define snmp_delete_ipaddridx_tree(ni) -#define snmp_insert_iprteidx_tree(dflt, ni) -#define snmp_delete_iprteidx_tree(dflt, ni) - -/* ICMP */ -#define snmp_inc_icmpinmsgs() -#define snmp_inc_icmpinerrors() -#define snmp_inc_icmpindestunreachs() -#define snmp_inc_icmpintimeexcds() -#define snmp_inc_icmpinparmprobs() -#define snmp_inc_icmpinsrcquenchs() -#define snmp_inc_icmpinredirects() -#define snmp_inc_icmpinechos() -#define snmp_inc_icmpinechoreps() -#define snmp_inc_icmpintimestamps() -#define snmp_inc_icmpintimestampreps() -#define snmp_inc_icmpinaddrmasks() -#define snmp_inc_icmpinaddrmaskreps() -#define snmp_inc_icmpoutmsgs() -#define snmp_inc_icmpouterrors() -#define snmp_inc_icmpoutdestunreachs() -#define snmp_inc_icmpouttimeexcds() -#define snmp_inc_icmpoutparmprobs() -#define snmp_inc_icmpoutsrcquenchs() -#define snmp_inc_icmpoutredirects() -#define snmp_inc_icmpoutechos() -#define snmp_inc_icmpoutechoreps() -#define snmp_inc_icmpouttimestamps() -#define snmp_inc_icmpouttimestampreps() -#define snmp_inc_icmpoutaddrmasks() -#define snmp_inc_icmpoutaddrmaskreps() -/* TCP */ -#define snmp_inc_tcpactiveopens() -#define snmp_inc_tcppassiveopens() -#define snmp_inc_tcpattemptfails() -#define snmp_inc_tcpestabresets() -#define snmp_inc_tcpinsegs() -#define snmp_inc_tcpoutsegs() -#define snmp_inc_tcpretranssegs() -#define snmp_inc_tcpinerrs() -#define snmp_inc_tcpoutrsts() - -/* UDP */ -#define snmp_inc_udpindatagrams() -#define snmp_inc_udpnoports() -#define snmp_inc_udpinerrors() -#define snmp_inc_udpoutdatagrams() -#define snmp_insert_udpidx_tree(pcb) -#define snmp_delete_udpidx_tree(pcb) - -/* SNMP */ -#define snmp_inc_snmpinpkts() -#define snmp_inc_snmpoutpkts() -#define snmp_inc_snmpinbadversions() -#define snmp_inc_snmpinbadcommunitynames() -#define snmp_inc_snmpinbadcommunityuses() -#define snmp_inc_snmpinasnparseerrs() -#define snmp_inc_snmpintoobigs() -#define snmp_inc_snmpinnosuchnames() -#define snmp_inc_snmpinbadvalues() -#define snmp_inc_snmpinreadonlys() -#define snmp_inc_snmpingenerrs() -#define snmp_add_snmpintotalreqvars(value) -#define snmp_add_snmpintotalsetvars(value) -#define snmp_inc_snmpingetrequests() -#define snmp_inc_snmpingetnexts() -#define snmp_inc_snmpinsetrequests() -#define snmp_inc_snmpingetresponses() -#define snmp_inc_snmpintraps() -#define snmp_inc_snmpouttoobigs() -#define snmp_inc_snmpoutnosuchnames() -#define snmp_inc_snmpoutbadvalues() -#define snmp_inc_snmpoutgenerrs() -#define snmp_inc_snmpoutgetrequests() -#define snmp_inc_snmpoutgetnexts() -#define snmp_inc_snmpoutsetrequests() -#define snmp_inc_snmpoutgetresponses() -#define snmp_inc_snmpouttraps() -#define snmp_get_snmpgrpid_ptr(oid) -#define snmp_set_snmpenableauthentraps(value) -#define snmp_get_snmpenableauthentraps(value) - -#endif /* LWIP_SNMP */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_SNMP_H__ */ +/* + * Copyright (c) 2001, 2002 Leon Woestenberg + * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Leon Woestenberg + * + */ +#ifndef __LWIP_SNMP_H__ +#define __LWIP_SNMP_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lwip/ip_addr.h" + +struct udp_pcb; +struct netif; + +/** + * @see RFC1213, "MIB-II, 6. Definitions" + */ +enum snmp_ifType { + snmp_ifType_other=1, /* none of the following */ + snmp_ifType_regular1822, + snmp_ifType_hdh1822, + snmp_ifType_ddn_x25, + snmp_ifType_rfc877_x25, + snmp_ifType_ethernet_csmacd, + snmp_ifType_iso88023_csmacd, + snmp_ifType_iso88024_tokenBus, + snmp_ifType_iso88025_tokenRing, + snmp_ifType_iso88026_man, + snmp_ifType_starLan, + snmp_ifType_proteon_10Mbit, + snmp_ifType_proteon_80Mbit, + snmp_ifType_hyperchannel, + snmp_ifType_fddi, + snmp_ifType_lapb, + snmp_ifType_sdlc, + snmp_ifType_ds1, /* T-1 */ + snmp_ifType_e1, /* european equiv. of T-1 */ + snmp_ifType_basicISDN, + snmp_ifType_primaryISDN, /* proprietary serial */ + snmp_ifType_propPointToPointSerial, + snmp_ifType_ppp, + snmp_ifType_softwareLoopback, + snmp_ifType_eon, /* CLNP over IP [11] */ + snmp_ifType_ethernet_3Mbit, + snmp_ifType_nsip, /* XNS over IP */ + snmp_ifType_slip, /* generic SLIP */ + snmp_ifType_ultra, /* ULTRA technologies */ + snmp_ifType_ds3, /* T-3 */ + snmp_ifType_sip, /* SMDS */ + snmp_ifType_frame_relay +}; + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +/** SNMP "sysuptime" Interval */ +#define SNMP_SYSUPTIME_INTERVAL 10 + +/** fixed maximum length for object identifier type */ +#define LWIP_SNMP_OBJ_ID_LEN 32 + +/** internal object identifier representation */ +struct snmp_obj_id +{ + u8_t len; + s32_t id[LWIP_SNMP_OBJ_ID_LEN]; +}; + +/* system */ +void snmp_set_sysdesr(u8_t* str, u8_t* len); +void snmp_set_sysobjid(struct snmp_obj_id *oid); +void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid); +void snmp_inc_sysuptime(void); +void snmp_add_sysuptime(u32_t value); +void snmp_get_sysuptime(u32_t *value); +void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen); +void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen); +void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen); + +/* network interface */ +void snmp_add_ifinoctets(struct netif *ni, u32_t value); +void snmp_inc_ifinucastpkts(struct netif *ni); +void snmp_inc_ifinnucastpkts(struct netif *ni); +void snmp_inc_ifindiscards(struct netif *ni); +void snmp_add_ifoutoctets(struct netif *ni, u32_t value); +void snmp_inc_ifoutucastpkts(struct netif *ni); +void snmp_inc_ifoutnucastpkts(struct netif *ni); +void snmp_inc_ifoutdiscards(struct netif *ni); +void snmp_inc_iflist(void); +void snmp_dec_iflist(void); + +/* ARP (for atTable and ipNetToMediaTable) */ +void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip); +void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip); + +/* IP */ +void snmp_inc_ipinreceives(void); +void snmp_inc_ipinhdrerrors(void); +void snmp_inc_ipinaddrerrors(void); +void snmp_inc_ipforwdatagrams(void); +void snmp_inc_ipinunknownprotos(void); +void snmp_inc_ipindiscards(void); +void snmp_inc_ipindelivers(void); +void snmp_inc_ipoutrequests(void); +void snmp_inc_ipoutdiscards(void); +void snmp_inc_ipoutnoroutes(void); +void snmp_inc_ipreasmreqds(void); +void snmp_inc_ipreasmoks(void); +void snmp_inc_ipreasmfails(void); +void snmp_inc_ipfragoks(void); +void snmp_inc_ipfragfails(void); +void snmp_inc_ipfragcreates(void); +void snmp_inc_iproutingdiscards(void); +void snmp_insert_ipaddridx_tree(struct netif *ni); +void snmp_delete_ipaddridx_tree(struct netif *ni); +void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni); +void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni); + +/* ICMP */ +void snmp_inc_icmpinmsgs(void); +void snmp_inc_icmpinerrors(void); +void snmp_inc_icmpindestunreachs(void); +void snmp_inc_icmpintimeexcds(void); +void snmp_inc_icmpinparmprobs(void); +void snmp_inc_icmpinsrcquenchs(void); +void snmp_inc_icmpinredirects(void); +void snmp_inc_icmpinechos(void); +void snmp_inc_icmpinechoreps(void); +void snmp_inc_icmpintimestamps(void); +void snmp_inc_icmpintimestampreps(void); +void snmp_inc_icmpinaddrmasks(void); +void snmp_inc_icmpinaddrmaskreps(void); +void snmp_inc_icmpoutmsgs(void); +void snmp_inc_icmpouterrors(void); +void snmp_inc_icmpoutdestunreachs(void); +void snmp_inc_icmpouttimeexcds(void); +void snmp_inc_icmpoutparmprobs(void); +void snmp_inc_icmpoutsrcquenchs(void); +void snmp_inc_icmpoutredirects(void); +void snmp_inc_icmpoutechos(void); +void snmp_inc_icmpoutechoreps(void); +void snmp_inc_icmpouttimestamps(void); +void snmp_inc_icmpouttimestampreps(void); +void snmp_inc_icmpoutaddrmasks(void); +void snmp_inc_icmpoutaddrmaskreps(void); + +/* TCP */ +void snmp_inc_tcpactiveopens(void); +void snmp_inc_tcppassiveopens(void); +void snmp_inc_tcpattemptfails(void); +void snmp_inc_tcpestabresets(void); +void snmp_inc_tcpinsegs(void); +void snmp_inc_tcpoutsegs(void); +void snmp_inc_tcpretranssegs(void); +void snmp_inc_tcpinerrs(void); +void snmp_inc_tcpoutrsts(void); + +/* UDP */ +void snmp_inc_udpindatagrams(void); +void snmp_inc_udpnoports(void); +void snmp_inc_udpinerrors(void); +void snmp_inc_udpoutdatagrams(void); +void snmp_insert_udpidx_tree(struct udp_pcb *pcb); +void snmp_delete_udpidx_tree(struct udp_pcb *pcb); + +/* SNMP */ +void snmp_inc_snmpinpkts(void); +void snmp_inc_snmpoutpkts(void); +void snmp_inc_snmpinbadversions(void); +void snmp_inc_snmpinbadcommunitynames(void); +void snmp_inc_snmpinbadcommunityuses(void); +void snmp_inc_snmpinasnparseerrs(void); +void snmp_inc_snmpintoobigs(void); +void snmp_inc_snmpinnosuchnames(void); +void snmp_inc_snmpinbadvalues(void); +void snmp_inc_snmpinreadonlys(void); +void snmp_inc_snmpingenerrs(void); +void snmp_add_snmpintotalreqvars(u8_t value); +void snmp_add_snmpintotalsetvars(u8_t value); +void snmp_inc_snmpingetrequests(void); +void snmp_inc_snmpingetnexts(void); +void snmp_inc_snmpinsetrequests(void); +void snmp_inc_snmpingetresponses(void); +void snmp_inc_snmpintraps(void); +void snmp_inc_snmpouttoobigs(void); +void snmp_inc_snmpoutnosuchnames(void); +void snmp_inc_snmpoutbadvalues(void); +void snmp_inc_snmpoutgenerrs(void); +void snmp_inc_snmpoutgetrequests(void); +void snmp_inc_snmpoutgetnexts(void); +void snmp_inc_snmpoutsetrequests(void); +void snmp_inc_snmpoutgetresponses(void); +void snmp_inc_snmpouttraps(void); +void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid); +void snmp_set_snmpenableauthentraps(u8_t *value); +void snmp_get_snmpenableauthentraps(u8_t *value); + +/* LWIP_SNMP support not available */ +/* define everything to be empty */ +#else + +/* system */ +#define snmp_set_sysdesr(str, len) +#define snmp_set_sysobjid(oid); +#define snmp_get_sysobjid_ptr(oid) +#define snmp_inc_sysuptime() +#define snmp_add_sysuptime(value) +#define snmp_get_sysuptime(value) +#define snmp_set_syscontact(ocstr, ocstrlen); +#define snmp_set_sysname(ocstr, ocstrlen); +#define snmp_set_syslocation(ocstr, ocstrlen); + +/* network interface */ +#define snmp_add_ifinoctets(ni,value) +#define snmp_inc_ifinucastpkts(ni) +#define snmp_inc_ifinnucastpkts(ni) +#define snmp_inc_ifindiscards(ni) +#define snmp_add_ifoutoctets(ni,value) +#define snmp_inc_ifoutucastpkts(ni) +#define snmp_inc_ifoutnucastpkts(ni) +#define snmp_inc_ifoutdiscards(ni) +#define snmp_inc_iflist() +#define snmp_dec_iflist() + +/* ARP */ +#define snmp_insert_arpidx_tree(ni,ip) +#define snmp_delete_arpidx_tree(ni,ip) + +/* IP */ +#define snmp_inc_ipinreceives() +#define snmp_inc_ipinhdrerrors() +#define snmp_inc_ipinaddrerrors() +#define snmp_inc_ipforwdatagrams() +#define snmp_inc_ipinunknownprotos() +#define snmp_inc_ipindiscards() +#define snmp_inc_ipindelivers() +#define snmp_inc_ipoutrequests() +#define snmp_inc_ipoutdiscards() +#define snmp_inc_ipoutnoroutes() +#define snmp_inc_ipreasmreqds() +#define snmp_inc_ipreasmoks() +#define snmp_inc_ipreasmfails() +#define snmp_inc_ipfragoks() +#define snmp_inc_ipfragfails() +#define snmp_inc_ipfragcreates() +#define snmp_inc_iproutingdiscards() +#define snmp_insert_ipaddridx_tree(ni) +#define snmp_delete_ipaddridx_tree(ni) +#define snmp_insert_iprteidx_tree(dflt, ni) +#define snmp_delete_iprteidx_tree(dflt, ni) + +/* ICMP */ +#define snmp_inc_icmpinmsgs() +#define snmp_inc_icmpinerrors() +#define snmp_inc_icmpindestunreachs() +#define snmp_inc_icmpintimeexcds() +#define snmp_inc_icmpinparmprobs() +#define snmp_inc_icmpinsrcquenchs() +#define snmp_inc_icmpinredirects() +#define snmp_inc_icmpinechos() +#define snmp_inc_icmpinechoreps() +#define snmp_inc_icmpintimestamps() +#define snmp_inc_icmpintimestampreps() +#define snmp_inc_icmpinaddrmasks() +#define snmp_inc_icmpinaddrmaskreps() +#define snmp_inc_icmpoutmsgs() +#define snmp_inc_icmpouterrors() +#define snmp_inc_icmpoutdestunreachs() +#define snmp_inc_icmpouttimeexcds() +#define snmp_inc_icmpoutparmprobs() +#define snmp_inc_icmpoutsrcquenchs() +#define snmp_inc_icmpoutredirects() +#define snmp_inc_icmpoutechos() +#define snmp_inc_icmpoutechoreps() +#define snmp_inc_icmpouttimestamps() +#define snmp_inc_icmpouttimestampreps() +#define snmp_inc_icmpoutaddrmasks() +#define snmp_inc_icmpoutaddrmaskreps() +/* TCP */ +#define snmp_inc_tcpactiveopens() +#define snmp_inc_tcppassiveopens() +#define snmp_inc_tcpattemptfails() +#define snmp_inc_tcpestabresets() +#define snmp_inc_tcpinsegs() +#define snmp_inc_tcpoutsegs() +#define snmp_inc_tcpretranssegs() +#define snmp_inc_tcpinerrs() +#define snmp_inc_tcpoutrsts() + +/* UDP */ +#define snmp_inc_udpindatagrams() +#define snmp_inc_udpnoports() +#define snmp_inc_udpinerrors() +#define snmp_inc_udpoutdatagrams() +#define snmp_insert_udpidx_tree(pcb) +#define snmp_delete_udpidx_tree(pcb) + +/* SNMP */ +#define snmp_inc_snmpinpkts() +#define snmp_inc_snmpoutpkts() +#define snmp_inc_snmpinbadversions() +#define snmp_inc_snmpinbadcommunitynames() +#define snmp_inc_snmpinbadcommunityuses() +#define snmp_inc_snmpinasnparseerrs() +#define snmp_inc_snmpintoobigs() +#define snmp_inc_snmpinnosuchnames() +#define snmp_inc_snmpinbadvalues() +#define snmp_inc_snmpinreadonlys() +#define snmp_inc_snmpingenerrs() +#define snmp_add_snmpintotalreqvars(value) +#define snmp_add_snmpintotalsetvars(value) +#define snmp_inc_snmpingetrequests() +#define snmp_inc_snmpingetnexts() +#define snmp_inc_snmpinsetrequests() +#define snmp_inc_snmpingetresponses() +#define snmp_inc_snmpintraps() +#define snmp_inc_snmpouttoobigs() +#define snmp_inc_snmpoutnosuchnames() +#define snmp_inc_snmpoutbadvalues() +#define snmp_inc_snmpoutgenerrs() +#define snmp_inc_snmpoutgetrequests() +#define snmp_inc_snmpoutgetnexts() +#define snmp_inc_snmpoutsetrequests() +#define snmp_inc_snmpoutgetresponses() +#define snmp_inc_snmpouttraps() +#define snmp_get_snmpgrpid_ptr(oid) +#define snmp_set_snmpenableauthentraps(value) +#define snmp_get_snmpenableauthentraps(value) + +#endif /* LWIP_SNMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_SNMP_H__ */ diff --git a/include/lwip/lwip/snmp_asn1.h b/include/lwip/lwip/snmp_asn1.h index fbfb68b9..605fa3f1 100644 --- a/include/lwip/lwip/snmp_asn1.h +++ b/include/lwip/lwip/snmp_asn1.h @@ -1,101 +1,101 @@ -/** - * @file - * Abstract Syntax Notation One (ISO 8824, 8825) codec. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons - */ - -#ifndef __LWIP_SNMP_ASN1_H__ -#define __LWIP_SNMP_ASN1_H__ - -#include "lwip/opt.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/snmp.h" - -#if LWIP_SNMP - -#ifdef __cplusplus -extern "C" { -#endif - -#define SNMP_ASN1_UNIV (0) /* (!0x80 | !0x40) */ -#define SNMP_ASN1_APPLIC (0x40) /* (!0x80 | 0x40) */ -#define SNMP_ASN1_CONTXT (0x80) /* ( 0x80 | !0x40) */ - -#define SNMP_ASN1_CONSTR (0x20) /* ( 0x20) */ -#define SNMP_ASN1_PRIMIT (0) /* (!0x20) */ - -/* universal tags */ -#define SNMP_ASN1_INTEG 2 -#define SNMP_ASN1_OC_STR 4 -#define SNMP_ASN1_NUL 5 -#define SNMP_ASN1_OBJ_ID 6 -#define SNMP_ASN1_SEQ 16 - -/* application specific (SNMP) tags */ -#define SNMP_ASN1_IPADDR 0 /* octet string size(4) */ -#define SNMP_ASN1_COUNTER 1 /* u32_t */ -#define SNMP_ASN1_GAUGE 2 /* u32_t */ -#define SNMP_ASN1_TIMETICKS 3 /* u32_t */ -#define SNMP_ASN1_OPAQUE 4 /* octet string */ - -/* context specific (SNMP) tags */ -#define SNMP_ASN1_PDU_GET_REQ 0 -#define SNMP_ASN1_PDU_GET_NEXT_REQ 1 -#define SNMP_ASN1_PDU_GET_RESP 2 -#define SNMP_ASN1_PDU_SET_REQ 3 -#define SNMP_ASN1_PDU_TRAP 4 - -err_t snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type); -err_t snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length); -err_t snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value); -err_t snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value); -err_t snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid); -err_t snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw); - -void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed); -void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed); -void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed); -void snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed); -err_t snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type); -err_t snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length); -err_t snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value); -err_t snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value); -err_t snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident); -err_t snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* __LWIP_SNMP_ASN1_H__ */ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) codec. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_ASN1_H__ +#define __LWIP_SNMP_ASN1_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/snmp.h" + +#if LWIP_SNMP + +#ifdef __cplusplus +extern "C" { +#endif + +#define SNMP_ASN1_UNIV (0) /* (!0x80 | !0x40) */ +#define SNMP_ASN1_APPLIC (0x40) /* (!0x80 | 0x40) */ +#define SNMP_ASN1_CONTXT (0x80) /* ( 0x80 | !0x40) */ + +#define SNMP_ASN1_CONSTR (0x20) /* ( 0x20) */ +#define SNMP_ASN1_PRIMIT (0) /* (!0x20) */ + +/* universal tags */ +#define SNMP_ASN1_INTEG 2 +#define SNMP_ASN1_OC_STR 4 +#define SNMP_ASN1_NUL 5 +#define SNMP_ASN1_OBJ_ID 6 +#define SNMP_ASN1_SEQ 16 + +/* application specific (SNMP) tags */ +#define SNMP_ASN1_IPADDR 0 /* octet string size(4) */ +#define SNMP_ASN1_COUNTER 1 /* u32_t */ +#define SNMP_ASN1_GAUGE 2 /* u32_t */ +#define SNMP_ASN1_TIMETICKS 3 /* u32_t */ +#define SNMP_ASN1_OPAQUE 4 /* octet string */ + +/* context specific (SNMP) tags */ +#define SNMP_ASN1_PDU_GET_REQ 0 +#define SNMP_ASN1_PDU_GET_NEXT_REQ 1 +#define SNMP_ASN1_PDU_GET_RESP 2 +#define SNMP_ASN1_PDU_SET_REQ 3 +#define SNMP_ASN1_PDU_TRAP 4 + +err_t snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type); +err_t snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length); +err_t snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value); +err_t snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value); +err_t snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid); +err_t snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw); + +void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed); +void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed); +void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed); +void snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed); +err_t snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type); +err_t snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length); +err_t snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value); +err_t snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value); +err_t snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident); +err_t snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_ASN1_H__ */ diff --git a/include/lwip/lwip/snmp_msg.h b/include/lwip/lwip/snmp_msg.h index 656924e8..1183e3a9 100644 --- a/include/lwip/lwip/snmp_msg.h +++ b/include/lwip/lwip/snmp_msg.h @@ -1,315 +1,315 @@ -/** - * @file - * SNMP Agent message handling structures. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons - */ - -#ifndef __LWIP_SNMP_MSG_H__ -#define __LWIP_SNMP_MSG_H__ - -#include "lwip/opt.h" -#include "lwip/snmp.h" -#include "lwip/snmp_structs.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" - -#if LWIP_SNMP - -#if SNMP_PRIVATE_MIB -/* When using a private MIB, you have to create a file 'private_mib.h' that contains - * a 'struct mib_array_node mib_private' which contains your MIB. */ -#include "private_mib.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* The listen port of the SNMP agent. Clients have to make their requests to - this port. Most standard clients won't work if you change this! */ -#ifndef SNMP_IN_PORT -#define SNMP_IN_PORT 161 -#endif -/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't - work if you change this! */ -#ifndef SNMP_TRAP_PORT -#define SNMP_TRAP_PORT 162 -#endif - -#define SNMP_ES_NOERROR 0 -#define SNMP_ES_TOOBIG 1 -#define SNMP_ES_NOSUCHNAME 2 -#define SNMP_ES_BADVALUE 3 -#define SNMP_ES_READONLY 4 -#define SNMP_ES_GENERROR 5 - -#define SNMP_GENTRAP_COLDSTART 0 -#define SNMP_GENTRAP_WARMSTART 1 -#define SNMP_GENTRAP_AUTHFAIL 4 -#define SNMP_GENTRAP_ENTERPRISESPC 6 - -struct snmp_varbind -{ - /* next pointer, NULL for last in list */ - struct snmp_varbind *next; - /* previous pointer, NULL for first in list */ - struct snmp_varbind *prev; - - /* object identifier length (in s32_t) */ - u8_t ident_len; - /* object identifier array */ - s32_t *ident; - - /* object value ASN1 type */ - u8_t value_type; - /* object value length (in u8_t) */ - u8_t value_len; - /* object value */ - void *value; - - /* encoding varbind seq length length */ - u8_t seqlenlen; - /* encoding object identifier length length */ - u8_t olenlen; - /* encoding object value length length */ - u8_t vlenlen; - /* encoding varbind seq length */ - u16_t seqlen; - /* encoding object identifier length */ - u16_t olen; - /* encoding object value length */ - u16_t vlen; -}; - -struct snmp_varbind_root -{ - struct snmp_varbind *head; - struct snmp_varbind *tail; - /* number of variable bindings in list */ - u8_t count; - /* encoding varbind-list seq length length */ - u8_t seqlenlen; - /* encoding varbind-list seq length */ - u16_t seqlen; -}; - -/** output response message header length fields */ -struct snmp_resp_header_lengths -{ - /* encoding error-index length length */ - u8_t erridxlenlen; - /* encoding error-status length length */ - u8_t errstatlenlen; - /* encoding request id length length */ - u8_t ridlenlen; - /* encoding pdu length length */ - u8_t pdulenlen; - /* encoding community length length */ - u8_t comlenlen; - /* encoding version length length */ - u8_t verlenlen; - /* encoding sequence length length */ - u8_t seqlenlen; - - /* encoding error-index length */ - u16_t erridxlen; - /* encoding error-status length */ - u16_t errstatlen; - /* encoding request id length */ - u16_t ridlen; - /* encoding pdu length */ - u16_t pdulen; - /* encoding community length */ - u16_t comlen; - /* encoding version length */ - u16_t verlen; - /* encoding sequence length */ - u16_t seqlen; -}; - -/** output response message header length fields */ -struct snmp_trap_header_lengths -{ - /* encoding timestamp length length */ - u8_t tslenlen; - /* encoding specific-trap length length */ - u8_t strplenlen; - /* encoding generic-trap length length */ - u8_t gtrplenlen; - /* encoding agent-addr length length */ - u8_t aaddrlenlen; - /* encoding enterprise-id length length */ - u8_t eidlenlen; - /* encoding pdu length length */ - u8_t pdulenlen; - /* encoding community length length */ - u8_t comlenlen; - /* encoding version length length */ - u8_t verlenlen; - /* encoding sequence length length */ - u8_t seqlenlen; - - /* encoding timestamp length */ - u16_t tslen; - /* encoding specific-trap length */ - u16_t strplen; - /* encoding generic-trap length */ - u16_t gtrplen; - /* encoding agent-addr length */ - u16_t aaddrlen; - /* encoding enterprise-id length */ - u16_t eidlen; - /* encoding pdu length */ - u16_t pdulen; - /* encoding community length */ - u16_t comlen; - /* encoding version length */ - u16_t verlen; - /* encoding sequence length */ - u16_t seqlen; -}; - -/* Accepting new SNMP messages. */ -#define SNMP_MSG_EMPTY 0 -/* Search for matching object for variable binding. */ -#define SNMP_MSG_SEARCH_OBJ 1 -/* Perform SNMP operation on in-memory object. - Pass-through states, for symmetry only. */ -#define SNMP_MSG_INTERNAL_GET_OBJDEF 2 -#define SNMP_MSG_INTERNAL_GET_VALUE 3 -#define SNMP_MSG_INTERNAL_SET_TEST 4 -#define SNMP_MSG_INTERNAL_GET_OBJDEF_S 5 -#define SNMP_MSG_INTERNAL_SET_VALUE 6 -/* Perform SNMP operation on object located externally. - In theory this could be used for building a proxy agent. - Practical use is for an enterprise spc. app. gateway. */ -#define SNMP_MSG_EXTERNAL_GET_OBJDEF 7 -#define SNMP_MSG_EXTERNAL_GET_VALUE 8 -#define SNMP_MSG_EXTERNAL_SET_TEST 9 -#define SNMP_MSG_EXTERNAL_GET_OBJDEF_S 10 -#define SNMP_MSG_EXTERNAL_SET_VALUE 11 - -#define SNMP_COMMUNITY_STR_LEN 64 -struct snmp_msg_pstat -{ - /* lwIP local port (161) binding */ - struct udp_pcb *pcb; - /* source IP address */ - ip_addr_t sip; - /* source UDP port */ - u16_t sp; - /* request type */ - u8_t rt; - /* request ID */ - s32_t rid; - /* error status */ - s32_t error_status; - /* error index */ - s32_t error_index; - /* community name (zero terminated) */ - u8_t community[SNMP_COMMUNITY_STR_LEN + 1]; - /* community string length (exclusive zero term) */ - u8_t com_strlen; - /* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL_x */ - u8_t state; - /* saved arguments for MSG_EXTERNAL_x */ - struct mib_external_node *ext_mib_node; - struct snmp_name_ptr ext_name_ptr; - struct obj_def ext_object_def; - struct snmp_obj_id ext_oid; - /* index into input variable binding list */ - u8_t vb_idx; - /* ptr into input variable binding list */ - struct snmp_varbind *vb_ptr; - /* list of variable bindings from input */ - struct snmp_varbind_root invb; - /* list of variable bindings to output */ - struct snmp_varbind_root outvb; - /* output response lengths used in ASN encoding */ - struct snmp_resp_header_lengths rhl; -}; - -struct snmp_msg_trap -{ - /* lwIP local port (161) binding */ - struct udp_pcb *pcb; - /* destination IP address in network order */ - ip_addr_t dip; - - /* source enterprise ID (sysObjectID) */ - struct snmp_obj_id *enterprise; - /* source IP address, raw network order format */ - u8_t sip_raw[4]; - /* generic trap code */ - u32_t gen_trap; - /* specific trap code */ - u32_t spc_trap; - /* timestamp */ - u32_t ts; - /* list of variable bindings to output */ - struct snmp_varbind_root outvb; - /* output trap lengths used in ASN encoding */ - struct snmp_trap_header_lengths thl; -}; - -/** Agent Version constant, 0 = v1 oddity */ -extern const s32_t snmp_version; -/** Agent default "public" community string */ -extern const char snmp_publiccommunity[7]; - -extern struct snmp_msg_trap trap_msg; - -/** Agent setup, start listening to port 161. */ -void snmp_init(void); -void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable); -void snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst); - -/** Varbind-list functions. */ -struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len); -void snmp_varbind_free(struct snmp_varbind *vb); -void snmp_varbind_list_free(struct snmp_varbind_root *root); -void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb); -struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root); - -/** Handle an internal (recv) or external (private response) event. */ -void snmp_msg_event(u8_t request_id); -err_t snmp_send_response(struct snmp_msg_pstat *m_stat); -err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap); -void snmp_coldstart_trap(void); -void snmp_authfail_trap(void); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* __LWIP_SNMP_MSG_H__ */ +/** + * @file + * SNMP Agent message handling structures. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_MSG_H__ +#define __LWIP_SNMP_MSG_H__ + +#include "lwip/opt.h" +#include "lwip/snmp.h" +#include "lwip/snmp_structs.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#if LWIP_SNMP + +#if SNMP_PRIVATE_MIB +/* When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. */ +#include "private_mib.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* The listen port of the SNMP agent. Clients have to make their requests to + this port. Most standard clients won't work if you change this! */ +#ifndef SNMP_IN_PORT +#define SNMP_IN_PORT 161 +#endif +/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't + work if you change this! */ +#ifndef SNMP_TRAP_PORT +#define SNMP_TRAP_PORT 162 +#endif + +#define SNMP_ES_NOERROR 0 +#define SNMP_ES_TOOBIG 1 +#define SNMP_ES_NOSUCHNAME 2 +#define SNMP_ES_BADVALUE 3 +#define SNMP_ES_READONLY 4 +#define SNMP_ES_GENERROR 5 + +#define SNMP_GENTRAP_COLDSTART 0 +#define SNMP_GENTRAP_WARMSTART 1 +#define SNMP_GENTRAP_AUTHFAIL 4 +#define SNMP_GENTRAP_ENTERPRISESPC 6 + +struct snmp_varbind +{ + /* next pointer, NULL for last in list */ + struct snmp_varbind *next; + /* previous pointer, NULL for first in list */ + struct snmp_varbind *prev; + + /* object identifier length (in s32_t) */ + u8_t ident_len; + /* object identifier array */ + s32_t *ident; + + /* object value ASN1 type */ + u8_t value_type; + /* object value length (in u8_t) */ + u8_t value_len; + /* object value */ + void *value; + + /* encoding varbind seq length length */ + u8_t seqlenlen; + /* encoding object identifier length length */ + u8_t olenlen; + /* encoding object value length length */ + u8_t vlenlen; + /* encoding varbind seq length */ + u16_t seqlen; + /* encoding object identifier length */ + u16_t olen; + /* encoding object value length */ + u16_t vlen; +}; + +struct snmp_varbind_root +{ + struct snmp_varbind *head; + struct snmp_varbind *tail; + /* number of variable bindings in list */ + u8_t count; + /* encoding varbind-list seq length length */ + u8_t seqlenlen; + /* encoding varbind-list seq length */ + u16_t seqlen; +}; + +/** output response message header length fields */ +struct snmp_resp_header_lengths +{ + /* encoding error-index length length */ + u8_t erridxlenlen; + /* encoding error-status length length */ + u8_t errstatlenlen; + /* encoding request id length length */ + u8_t ridlenlen; + /* encoding pdu length length */ + u8_t pdulenlen; + /* encoding community length length */ + u8_t comlenlen; + /* encoding version length length */ + u8_t verlenlen; + /* encoding sequence length length */ + u8_t seqlenlen; + + /* encoding error-index length */ + u16_t erridxlen; + /* encoding error-status length */ + u16_t errstatlen; + /* encoding request id length */ + u16_t ridlen; + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding version length */ + u16_t verlen; + /* encoding sequence length */ + u16_t seqlen; +}; + +/** output response message header length fields */ +struct snmp_trap_header_lengths +{ + /* encoding timestamp length length */ + u8_t tslenlen; + /* encoding specific-trap length length */ + u8_t strplenlen; + /* encoding generic-trap length length */ + u8_t gtrplenlen; + /* encoding agent-addr length length */ + u8_t aaddrlenlen; + /* encoding enterprise-id length length */ + u8_t eidlenlen; + /* encoding pdu length length */ + u8_t pdulenlen; + /* encoding community length length */ + u8_t comlenlen; + /* encoding version length length */ + u8_t verlenlen; + /* encoding sequence length length */ + u8_t seqlenlen; + + /* encoding timestamp length */ + u16_t tslen; + /* encoding specific-trap length */ + u16_t strplen; + /* encoding generic-trap length */ + u16_t gtrplen; + /* encoding agent-addr length */ + u16_t aaddrlen; + /* encoding enterprise-id length */ + u16_t eidlen; + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding version length */ + u16_t verlen; + /* encoding sequence length */ + u16_t seqlen; +}; + +/* Accepting new SNMP messages. */ +#define SNMP_MSG_EMPTY 0 +/* Search for matching object for variable binding. */ +#define SNMP_MSG_SEARCH_OBJ 1 +/* Perform SNMP operation on in-memory object. + Pass-through states, for symmetry only. */ +#define SNMP_MSG_INTERNAL_GET_OBJDEF 2 +#define SNMP_MSG_INTERNAL_GET_VALUE 3 +#define SNMP_MSG_INTERNAL_SET_TEST 4 +#define SNMP_MSG_INTERNAL_GET_OBJDEF_S 5 +#define SNMP_MSG_INTERNAL_SET_VALUE 6 +/* Perform SNMP operation on object located externally. + In theory this could be used for building a proxy agent. + Practical use is for an enterprise spc. app. gateway. */ +#define SNMP_MSG_EXTERNAL_GET_OBJDEF 7 +#define SNMP_MSG_EXTERNAL_GET_VALUE 8 +#define SNMP_MSG_EXTERNAL_SET_TEST 9 +#define SNMP_MSG_EXTERNAL_GET_OBJDEF_S 10 +#define SNMP_MSG_EXTERNAL_SET_VALUE 11 + +#define SNMP_COMMUNITY_STR_LEN 64 +struct snmp_msg_pstat +{ + /* lwIP local port (161) binding */ + struct udp_pcb *pcb; + /* source IP address */ + ip_addr_t sip; + /* source UDP port */ + u16_t sp; + /* request type */ + u8_t rt; + /* request ID */ + s32_t rid; + /* error status */ + s32_t error_status; + /* error index */ + s32_t error_index; + /* community name (zero terminated) */ + u8_t community[SNMP_COMMUNITY_STR_LEN + 1]; + /* community string length (exclusive zero term) */ + u8_t com_strlen; + /* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL_x */ + u8_t state; + /* saved arguments for MSG_EXTERNAL_x */ + struct mib_external_node *ext_mib_node; + struct snmp_name_ptr ext_name_ptr; + struct obj_def ext_object_def; + struct snmp_obj_id ext_oid; + /* index into input variable binding list */ + u8_t vb_idx; + /* ptr into input variable binding list */ + struct snmp_varbind *vb_ptr; + /* list of variable bindings from input */ + struct snmp_varbind_root invb; + /* list of variable bindings to output */ + struct snmp_varbind_root outvb; + /* output response lengths used in ASN encoding */ + struct snmp_resp_header_lengths rhl; +}; + +struct snmp_msg_trap +{ + /* lwIP local port (161) binding */ + struct udp_pcb *pcb; + /* destination IP address in network order */ + ip_addr_t dip; + + /* source enterprise ID (sysObjectID) */ + struct snmp_obj_id *enterprise; + /* source IP address, raw network order format */ + u8_t sip_raw[4]; + /* generic trap code */ + u32_t gen_trap; + /* specific trap code */ + u32_t spc_trap; + /* timestamp */ + u32_t ts; + /* list of variable bindings to output */ + struct snmp_varbind_root outvb; + /* output trap lengths used in ASN encoding */ + struct snmp_trap_header_lengths thl; +}; + +/** Agent Version constant, 0 = v1 oddity */ +extern const s32_t snmp_version; +/** Agent default "public" community string */ +extern const char snmp_publiccommunity[7]; + +extern struct snmp_msg_trap trap_msg; + +/** Agent setup, start listening to port 161. */ +void snmp_init(void); +void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable); +void snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst); + +/** Varbind-list functions. */ +struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len); +void snmp_varbind_free(struct snmp_varbind *vb); +void snmp_varbind_list_free(struct snmp_varbind_root *root); +void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb); +struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root); + +/** Handle an internal (recv) or external (private response) event. */ +void snmp_msg_event(u8_t request_id); +err_t snmp_send_response(struct snmp_msg_pstat *m_stat); +err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap); +void snmp_coldstart_trap(void); +void snmp_authfail_trap(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_MSG_H__ */ diff --git a/include/lwip/lwip/snmp_structs.h b/include/lwip/lwip/snmp_structs.h index f7193b9d..0d3b46a9 100644 --- a/include/lwip/lwip/snmp_structs.h +++ b/include/lwip/lwip/snmp_structs.h @@ -1,268 +1,268 @@ -/** - * @file - * Generic MIB tree structures. - * - * @todo namespace prefixes - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons - */ - -#ifndef __LWIP_SNMP_STRUCTS_H__ -#define __LWIP_SNMP_STRUCTS_H__ - -#include "lwip/opt.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/snmp.h" - -#if SNMP_PRIVATE_MIB -/* When using a private MIB, you have to create a file 'private_mib.h' that contains - * a 'struct mib_array_node mib_private' which contains your MIB. */ -#include "private_mib.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* MIB object instance */ -#define MIB_OBJECT_NONE 0 -#define MIB_OBJECT_SCALAR 1 -#define MIB_OBJECT_TAB 2 - -/* MIB access types */ -#define MIB_ACCESS_READ 1 -#define MIB_ACCESS_WRITE 2 - -/* MIB object access */ -#define MIB_OBJECT_READ_ONLY MIB_ACCESS_READ -#define MIB_OBJECT_READ_WRITE (MIB_ACCESS_READ | MIB_ACCESS_WRITE) -#define MIB_OBJECT_WRITE_ONLY MIB_ACCESS_WRITE -#define MIB_OBJECT_NOT_ACCESSIBLE 0 - -/** object definition returned by (get_object_def)() */ -struct obj_def -{ - /* MIB_OBJECT_NONE (0), MIB_OBJECT_SCALAR (1), MIB_OBJECT_TAB (2) */ - u8_t instance; - /* 0 read-only, 1 read-write, 2 write-only, 3 not-accessible */ - u8_t access; - /* ASN type for this object */ - u8_t asn_type; - /* value length (host length) */ - u16_t v_len; - /* length of instance part of supplied object identifier */ - u8_t id_inst_len; - /* instance part of supplied object identifier */ - s32_t *id_inst_ptr; -}; - -struct snmp_name_ptr -{ - u8_t ident_len; - s32_t *ident; -}; - -/** MIB const scalar (.0) node */ -#define MIB_NODE_SC 0x01 -/** MIB const array node */ -#define MIB_NODE_AR 0x02 -/** MIB array node (mem_malloced from RAM) */ -#define MIB_NODE_RA 0x03 -/** MIB list root node (mem_malloced from RAM) */ -#define MIB_NODE_LR 0x04 -/** MIB node for external objects */ -#define MIB_NODE_EX 0x05 - -/** node "base class" layout, the mandatory fields for a node */ -struct mib_node -{ - /** returns struct obj_def for the given object identifier */ - void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); - /** returns object value for the given object identifier, - @note the caller must allocate at least len bytes for the value */ - void (*get_value)(struct obj_def *od, u16_t len, void *value); - /** tests length and/or range BEFORE setting */ - u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); - /** sets object value, only to be called when set_test() */ - void (*set_value)(struct obj_def *od, u16_t len, void *value); - /** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */ - u8_t node_type; - /* array or max list length */ - u16_t maxlength; -}; - -/** derived node for scalars .0 index */ -typedef struct mib_node mib_scalar_node; - -/** derived node, points to a fixed size const array - of sub-identifiers plus a 'child' pointer */ -struct mib_array_node -{ - /* inherited "base class" members */ - void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); - void (*get_value)(struct obj_def *od, u16_t len, void *value); - u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); - void (*set_value)(struct obj_def *od, u16_t len, void *value); - - u8_t node_type; - u16_t maxlength; - - /* additional struct members */ - const s32_t *objid; - struct mib_node* const *nptr; -}; - -/** derived node, points to a fixed size mem_malloced array - of sub-identifiers plus a 'child' pointer */ -struct mib_ram_array_node -{ - /* inherited "base class" members */ - void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); - void (*get_value)(struct obj_def *od, u16_t len, void *value); - u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); - void (*set_value)(struct obj_def *od, u16_t len, void *value); - - u8_t node_type; - u16_t maxlength; - - /* aditional struct members */ - s32_t *objid; - struct mib_node **nptr; -}; - -struct mib_list_node -{ - struct mib_list_node *prev; - struct mib_list_node *next; - s32_t objid; - struct mib_node *nptr; -}; - -/** derived node, points to a doubly linked list - of sub-identifiers plus a 'child' pointer */ -struct mib_list_rootnode -{ - /* inherited "base class" members */ - void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); - void (*get_value)(struct obj_def *od, u16_t len, void *value); - u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); - void (*set_value)(struct obj_def *od, u16_t len, void *value); - - u8_t node_type; - u16_t maxlength; - - /* additional struct members */ - struct mib_list_node *head; - struct mib_list_node *tail; - /* counts list nodes in list */ - u16_t count; -}; - -/** derived node, has access functions for mib object in external memory or device - using 'tree_level' and 'idx', with a range 0 .. (level_length() - 1) */ -struct mib_external_node -{ - /* inherited "base class" members */ - void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); - void (*get_value)(struct obj_def *od, u16_t len, void *value); - u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); - void (*set_value)(struct obj_def *od, u16_t len, void *value); - - u8_t node_type; - u16_t maxlength; - - /* additional struct members */ - /** points to an external (in memory) record of some sort of addressing - information, passed to and interpreted by the funtions below */ - void* addr_inf; - /** tree levels under this node */ - u8_t tree_levels; - /** number of objects at this level */ - u16_t (*level_length)(void* addr_inf, u8_t level); - /** compares object sub identifier with external id - return zero when equal, nonzero when unequal */ - s32_t (*ident_cmp)(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id); - void (*get_objid)(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id); - - /** async Questions */ - void (*get_object_def_q)(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident); - void (*get_value_q)(u8_t rid, struct obj_def *od); - void (*set_test_q)(u8_t rid, struct obj_def *od); - void (*set_value_q)(u8_t rid, struct obj_def *od, u16_t len, void *value); - /** async Answers */ - void (*get_object_def_a)(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od); - void (*get_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); - u8_t (*set_test_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); - void (*set_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); - /** async Panic Close (agent returns error reply, - e.g. used for external transaction cleanup) */ - void (*get_object_def_pc)(u8_t rid, u8_t ident_len, s32_t *ident); - void (*get_value_pc)(u8_t rid, struct obj_def *od); - void (*set_test_pc)(u8_t rid, struct obj_def *od); - void (*set_value_pc)(u8_t rid, struct obj_def *od); -}; - -/** export MIB tree from mib2.c */ -extern const struct mib_array_node internet; - -/** dummy function pointers for non-leaf MIB nodes from mib2.c */ -void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); -void noleafs_get_value(struct obj_def *od, u16_t len, void *value); -u8_t noleafs_set_test(struct obj_def *od, u16_t len, void *value); -void noleafs_set_value(struct obj_def *od, u16_t len, void *value); - -void snmp_oidtoip(s32_t *ident, ip_addr_t *ip); -void snmp_iptooid(ip_addr_t *ip, s32_t *ident); -void snmp_ifindextonetif(s32_t ifindex, struct netif **netif); -void snmp_netiftoifindex(struct netif *netif, s32_t *ifidx); - -struct mib_list_node* snmp_mib_ln_alloc(s32_t id); -void snmp_mib_ln_free(struct mib_list_node *ln); -struct mib_list_rootnode* snmp_mib_lrn_alloc(void); -void snmp_mib_lrn_free(struct mib_list_rootnode *lrn); - -s8_t snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn); -s8_t snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn); -struct mib_list_rootnode *snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n); - -struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np); -struct mib_node* snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); -u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident); -u8_t snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* __LWIP_SNMP_STRUCTS_H__ */ +/** + * @file + * Generic MIB tree structures. + * + * @todo namespace prefixes + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_STRUCTS_H__ +#define __LWIP_SNMP_STRUCTS_H__ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp.h" + +#if SNMP_PRIVATE_MIB +/* When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. */ +#include "private_mib.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* MIB object instance */ +#define MIB_OBJECT_NONE 0 +#define MIB_OBJECT_SCALAR 1 +#define MIB_OBJECT_TAB 2 + +/* MIB access types */ +#define MIB_ACCESS_READ 1 +#define MIB_ACCESS_WRITE 2 + +/* MIB object access */ +#define MIB_OBJECT_READ_ONLY MIB_ACCESS_READ +#define MIB_OBJECT_READ_WRITE (MIB_ACCESS_READ | MIB_ACCESS_WRITE) +#define MIB_OBJECT_WRITE_ONLY MIB_ACCESS_WRITE +#define MIB_OBJECT_NOT_ACCESSIBLE 0 + +/** object definition returned by (get_object_def)() */ +struct obj_def +{ + /* MIB_OBJECT_NONE (0), MIB_OBJECT_SCALAR (1), MIB_OBJECT_TAB (2) */ + u8_t instance; + /* 0 read-only, 1 read-write, 2 write-only, 3 not-accessible */ + u8_t access; + /* ASN type for this object */ + u8_t asn_type; + /* value length (host length) */ + u16_t v_len; + /* length of instance part of supplied object identifier */ + u8_t id_inst_len; + /* instance part of supplied object identifier */ + s32_t *id_inst_ptr; +}; + +struct snmp_name_ptr +{ + u8_t ident_len; + s32_t *ident; +}; + +/** MIB const scalar (.0) node */ +#define MIB_NODE_SC 0x01 +/** MIB const array node */ +#define MIB_NODE_AR 0x02 +/** MIB array node (mem_malloced from RAM) */ +#define MIB_NODE_RA 0x03 +/** MIB list root node (mem_malloced from RAM) */ +#define MIB_NODE_LR 0x04 +/** MIB node for external objects */ +#define MIB_NODE_EX 0x05 + +/** node "base class" layout, the mandatory fields for a node */ +struct mib_node +{ + /** returns struct obj_def for the given object identifier */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + /** returns object value for the given object identifier, + @note the caller must allocate at least len bytes for the value */ + void (*get_value)(struct obj_def *od, u16_t len, void *value); + /** tests length and/or range BEFORE setting */ + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + /** sets object value, only to be called when set_test() */ + void (*set_value)(struct obj_def *od, u16_t len, void *value); + /** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */ + u8_t node_type; + /* array or max list length */ + u16_t maxlength; +}; + +/** derived node for scalars .0 index */ +typedef struct mib_node mib_scalar_node; + +/** derived node, points to a fixed size const array + of sub-identifiers plus a 'child' pointer */ +struct mib_array_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + const s32_t *objid; + struct mib_node* const *nptr; +}; + +/** derived node, points to a fixed size mem_malloced array + of sub-identifiers plus a 'child' pointer */ +struct mib_ram_array_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* aditional struct members */ + s32_t *objid; + struct mib_node **nptr; +}; + +struct mib_list_node +{ + struct mib_list_node *prev; + struct mib_list_node *next; + s32_t objid; + struct mib_node *nptr; +}; + +/** derived node, points to a doubly linked list + of sub-identifiers plus a 'child' pointer */ +struct mib_list_rootnode +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + struct mib_list_node *head; + struct mib_list_node *tail; + /* counts list nodes in list */ + u16_t count; +}; + +/** derived node, has access functions for mib object in external memory or device + using 'tree_level' and 'idx', with a range 0 .. (level_length() - 1) */ +struct mib_external_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + /** points to an external (in memory) record of some sort of addressing + information, passed to and interpreted by the funtions below */ + void* addr_inf; + /** tree levels under this node */ + u8_t tree_levels; + /** number of objects at this level */ + u16_t (*level_length)(void* addr_inf, u8_t level); + /** compares object sub identifier with external id + return zero when equal, nonzero when unequal */ + s32_t (*ident_cmp)(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id); + void (*get_objid)(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id); + + /** async Questions */ + void (*get_object_def_q)(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident); + void (*get_value_q)(u8_t rid, struct obj_def *od); + void (*set_test_q)(u8_t rid, struct obj_def *od); + void (*set_value_q)(u8_t rid, struct obj_def *od, u16_t len, void *value); + /** async Answers */ + void (*get_object_def_a)(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + u8_t (*set_test_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + void (*set_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + /** async Panic Close (agent returns error reply, + e.g. used for external transaction cleanup) */ + void (*get_object_def_pc)(u8_t rid, u8_t ident_len, s32_t *ident); + void (*get_value_pc)(u8_t rid, struct obj_def *od); + void (*set_test_pc)(u8_t rid, struct obj_def *od); + void (*set_value_pc)(u8_t rid, struct obj_def *od); +}; + +/** export MIB tree from mib2.c */ +extern const struct mib_array_node internet; + +/** dummy function pointers for non-leaf MIB nodes from mib2.c */ +void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +void noleafs_get_value(struct obj_def *od, u16_t len, void *value); +u8_t noleafs_set_test(struct obj_def *od, u16_t len, void *value); +void noleafs_set_value(struct obj_def *od, u16_t len, void *value); + +void snmp_oidtoip(s32_t *ident, ip_addr_t *ip); +void snmp_iptooid(ip_addr_t *ip, s32_t *ident); +void snmp_ifindextonetif(s32_t ifindex, struct netif **netif); +void snmp_netiftoifindex(struct netif *netif, s32_t *ifidx); + +struct mib_list_node* snmp_mib_ln_alloc(s32_t id); +void snmp_mib_ln_free(struct mib_list_node *ln); +struct mib_list_rootnode* snmp_mib_lrn_alloc(void); +void snmp_mib_lrn_free(struct mib_list_rootnode *lrn); + +s8_t snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn); +s8_t snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn); +struct mib_list_rootnode *snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n); + +struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np); +struct mib_node* snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); +u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident); +u8_t snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_STRUCTS_H__ */ diff --git a/include/lwip/lwip/sockets.h b/include/lwip/lwip/sockets.h index 50c576c8..1f254e71 100644 --- a/include/lwip/lwip/sockets.h +++ b/include/lwip/lwip/sockets.h @@ -1,463 +1,463 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - - -#ifndef __LWIP_SOCKETS_H__ -#define __LWIP_SOCKETS_H__ - -#include "lwip/opt.h" - -#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include /* for size_t */ - -#include "lwip/ip_addr.h" -#include "lwip/inet.h" -#include "lwip/inet6.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED) -typedef u8_t sa_family_t; -#endif -/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED) -typedef u16_t in_port_t; -#endif - -/* members are in network byte order */ -struct sockaddr_in { - u8_t sin_len; - sa_family_t sin_family; - in_port_t sin_port; - struct in_addr sin_addr; -#define SIN_ZERO_LEN 8 - char sin_zero[SIN_ZERO_LEN]; -}; - -#if LWIP_IPV6 - -#define INET6_ADDRSTRLEN 46 - -struct sockaddr_in6 { - u8_t sin6_len; /* length of this structure */ - sa_family_t sin6_family; /* AF_INET6 */ - in_port_t sin6_port; /* Transport layer port # */ - u32_t sin6_flowinfo; /* IPv6 flow information */ - struct in6_addr sin6_addr; /* IPv6 address */ -}; -#endif /* LWIP_IPV6 */ - -struct sockaddr { - u8_t sa_len; - sa_family_t sa_family; -#if LWIP_IPV6 - char sa_data[22]; -#else /* LWIP_IPV6 */ - char sa_data[14]; -#endif /* LWIP_IPV6 */ -}; - -struct sockaddr_storage { - u8_t s2_len; - sa_family_t ss_family; - char s2_data1[2]; - u32_t s2_data2[3]; -#if LWIP_IPV6 - u32_t s2_data3[2]; -#endif /* LWIP_IPV6 */ -}; - -/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) -typedef u32_t socklen_t; -#endif - -/* Socket protocol types (TCP/UDP/RAW) */ -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 -#define SOCK_RAW 3 - -/* - * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) - */ -#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ -#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ -#define SO_REUSEADDR 0x0004 /* Allow local address reuse */ -#define SO_KEEPALIVE 0x0008 /* keep connections alive */ -#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ -#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ -#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ -#define SO_LINGER 0x0080 /* linger on close if data present */ -#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ -#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */ - -#define SO_DONTLINGER ((int)(~SO_LINGER)) - -/* - * Additional options, not kept in so_options. - */ -#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ -#define SO_RCVBUF 0x1002 /* receive buffer size */ -#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ -#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ -#define SO_SNDTIMEO 0x1005 /* Unimplemented: send timeout */ -#define SO_RCVTIMEO 0x1006 /* receive timeout */ -#define SO_ERROR 0x1007 /* get error status and clear */ -#define SO_TYPE 0x1008 /* get socket type */ -#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ -#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ - - -/* - * Structure used for manipulating linger option. - */ -struct linger { - int l_onoff; /* option on/off */ - int l_linger; /* linger time */ -}; - -/* - * Level number for (get/set)sockopt() to apply to socket itself. - */ -#define SOL_SOCKET 0xfff /* options for socket level */ - - -#define AF_UNSPEC 0 -#define AF_INET 2 -#if LWIP_IPV6 -#define AF_INET6 10 -#else /* LWIP_IPV6 */ -#define AF_INET6 AF_UNSPEC -#endif /* LWIP_IPV6 */ -#define PF_INET AF_INET -#define PF_INET6 AF_INET6 -#define PF_UNSPEC AF_UNSPEC - -#define IPPROTO_IP 0 -#define IPPROTO_TCP 6 -#define IPPROTO_UDP 17 -#if LWIP_IPV6 -#define IPPROTO_IPV6 41 -#endif /* LWIP_IPV6 */ -#define IPPROTO_UDPLITE 136 - -/* Flags we can use with send and recv. */ -#define MSG_PEEK 0x01 /* Peeks at an incoming message */ -#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ -#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ -#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ -#define MSG_MORE 0x10 /* Sender will send more */ - - -/* - * Options for level IPPROTO_IP - */ -#define IP_TOS 1 -#define IP_TTL 2 - -#if LWIP_TCP -/* - * Options for level IPPROTO_TCP - */ -#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ -#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */ -#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */ -#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */ -#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */ -#endif /* LWIP_TCP */ - -#if LWIP_IPV6 -/* - * Options for level IPPROTO_IPV6 - */ -#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */ -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE -/* - * Options for level IPPROTO_UDPLITE - */ -#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ -#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ -#endif /* LWIP_UDP && LWIP_UDPLITE*/ - - -#if LWIP_IGMP -/* - * Options and types for UDP multicast traffic handling - */ -#define IP_ADD_MEMBERSHIP 3 -#define IP_DROP_MEMBERSHIP 4 -#define IP_MULTICAST_TTL 5 -#define IP_MULTICAST_IF 6 -#define IP_MULTICAST_LOOP 7 - -typedef struct ip_mreq { - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_interface; /* local IP address of interface */ -} ip_mreq; -#endif /* LWIP_IGMP */ - -/* - * The Type of Service provides an indication of the abstract - * parameters of the quality of service desired. These parameters are - * to be used to guide the selection of the actual service parameters - * when transmitting a datagram through a particular network. Several - * networks offer service precedence, which somehow treats high - * precedence traffic as more important than other traffic (generally - * by accepting only traffic above a certain precedence at time of high - * load). The major choice is a three way tradeoff between low-delay, - * high-reliability, and high-throughput. - * The use of the Delay, Throughput, and Reliability indications may - * increase the cost (in some sense) of the service. In many networks - * better performance for one of these parameters is coupled with worse - * performance on another. Except for very unusual cases at most two - * of these three indications should be set. - */ -#define IPTOS_TOS_MASK 0x1E -#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 -#define IPTOS_LOWCOST 0x02 -#define IPTOS_MINCOST IPTOS_LOWCOST - -/* - * The Network Control precedence designation is intended to be used - * within a network only. The actual use and control of that - * designation is up to each network. The Internetwork Control - * designation is intended for use by gateway control originators only. - * If the actual use of these precedence designations is of concern to - * a particular network, it is the responsibility of that network to - * control the access to, and use of, those precedence designations. - */ -#define IPTOS_PREC_MASK 0xe0 -#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) -#define IPTOS_PREC_NETCONTROL 0xe0 -#define IPTOS_PREC_INTERNETCONTROL 0xc0 -#define IPTOS_PREC_CRITIC_ECP 0xa0 -#define IPTOS_PREC_FLASHOVERRIDE 0x80 -#define IPTOS_PREC_FLASH 0x60 -#define IPTOS_PREC_IMMEDIATE 0x40 -#define IPTOS_PREC_PRIORITY 0x20 -#define IPTOS_PREC_ROUTINE 0x00 - - -/* - * Commands for ioctlsocket(), taken from the BSD file fcntl.h. - * lwip_ioctl only supports FIONREAD and FIONBIO, for now - * - * Ioctl's have the command encoded in the lower word, - * and the size of any in or out parameters in the upper - * word. The high 2 bits of the upper word are used - * to encode the in/out status of the parameter; for now - * we restrict parameters to at most 128 bytes. - */ -#if !defined(FIONREAD) || !defined(FIONBIO) -#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ -#define IOC_VOID 0x20000000UL /* no parameters */ -#define IOC_OUT 0x40000000UL /* copy out parameters */ -#define IOC_IN 0x80000000UL /* copy in parameters */ -#define IOC_INOUT (IOC_IN|IOC_OUT) - /* 0x20000000 distinguishes new & - old ioctl's */ -#define _IO(x,y) (IOC_VOID|((x)<<8)|(y)) - -#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) - -#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) -#endif /* !defined(FIONREAD) || !defined(FIONBIO) */ - -#ifndef FIONREAD -#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */ -#endif -#ifndef FIONBIO -#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */ -#endif - -/* Socket I/O Controls: unimplemented */ -#ifndef SIOCSHIWAT -#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */ -#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */ -#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */ -#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */ -#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */ -#endif - -/* commands for fnctl */ -#ifndef F_GETFL -#define F_GETFL 3 -#endif -#ifndef F_SETFL -#define F_SETFL 4 -#endif - -/* File status flags and file access modes for fnctl, - these are bits in an int. */ -#ifndef O_NONBLOCK -#define O_NONBLOCK 1 /* nonblocking I/O */ -#endif -#ifndef O_NDELAY -#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */ -#endif - -#ifndef SHUT_RD - #define SHUT_RD 0 - #define SHUT_WR 1 - #define SHUT_RDWR 2 -#endif - -/* FD_SET used for lwip_select */ -#ifndef FD_SET - #undef FD_SETSIZE - /* Make FD_SETSIZE match NUM_SOCKETS in socket.c */ - #define FD_SETSIZE MEMP_NUM_NETCONN - #define FD_SET(n, p) ((p)->fd_bits[(n)/8] |= (1 << ((n) & 7))) - #define FD_CLR(n, p) ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7))) - #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] & (1 << ((n) & 7))) - #define FD_ZERO(p) memset((void*)(p),0,sizeof(*(p))) - - typedef struct fd_set { - unsigned char fd_bits [(FD_SETSIZE+7)/8]; - } fd_set; - -#endif /* FD_SET */ - -/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided - * by your system, set this to 0 and include in cc.h */ -#ifndef LWIP_TIMEVAL_PRIVATE -#define LWIP_TIMEVAL_PRIVATE 1 -#endif - -#if LWIP_TIMEVAL_PRIVATE -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; -#endif /* LWIP_TIMEVAL_PRIVATE */ - -void lwip_socket_init(void); - -int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); -int lwip_shutdown(int s, int how); -int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); -int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen); -int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); -int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); - - -/** - * set if lwip_close will use 4-handshake to close a tcp connection, - * - * @param req 1 , send rst pkt directly, when call lwip_close(),rather than 4-handshake. - * then all buffed PCB memory resource will be freed immediately - * 0, send Fin flag pkt other than rst pkt when call lwip_close(s) - * @return - */ -void lwip_force_close_set(char req); - -int lwip_close(int s); -int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); -int lwip_listen(int s, int backlog); -int lwip_recv(int s, void *mem, size_t len, int flags); -int lwip_read(int s, void *mem, size_t len); -int lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen); -int lwip_send(int s, const void *dataptr, size_t size, int flags); -int lwip_sendto(int s, const void *dataptr, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen); -int lwip_socket(int domain, int type, int protocol); -int lwip_write(int s, const void *dataptr, size_t size); -int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, - struct timeval *timeout); -int lwip_ioctl(int s, long cmd, void *argp); -int lwip_fcntl(int s, int cmd, int val); - -#if LWIP_COMPAT_SOCKETS && !defined(SOCKETS_MT) -#define accept(a,b,c) lwip_accept(a,b,c) -#define bind(a,b,c) lwip_bind(a,b,c) -#define shutdown(a,b) lwip_shutdown(a,b) -#define closesocket(s) lwip_close(s) -#define connect(a,b,c) lwip_connect(a,b,c) -#define getsockname(a,b,c) lwip_getsockname(a,b,c) -#define getpeername(a,b,c) lwip_getpeername(a,b,c) -#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e) -#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e) -#define listen(a,b) lwip_listen(a,b) -#define recv(a,b,c,d) lwip_recv(a,b,c,d) -#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f) -#define send(a,b,c,d) lwip_send(a,b,c,d) -#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f) -#define socket(a,b,c) lwip_socket(a,b,c) -#define select(a,b,c,d,e) lwip_select(a,b,c,d,e) -#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c) - -#if LWIP_POSIX_SOCKETS_IO_NAMES -#define read(a,b,c) lwip_read(a,b,c) -#define write(a,b,c) lwip_write(a,b,c) -#define close(s) lwip_close(s) -#define fcntl(a,b,c) lwip_fcntl(a,b,c) -#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ - -#if LWIP_IPV6 -#define inet_ntop(af,src,dst,size) \ - (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t *)(src),(dst),(size)) \ - : (((af) == AF_INET) ? ipaddr_ntoa_r((const ip_addr_t *)(src),(dst),(size)) : NULL)) -#define inet_pton(af,src,dst) \ - (((af) == AF_INET6) ? inet6_aton((src),(const ip6_addr_t *)(dst)) \ - : (((af) == AF_INET) ? inet_aton((src),(const ip_addr_t *)(dst)) : 0)) -#else /* LWIP_IPV6 */ -#define inet_ntop(af,src,dst,size) \ - (((af) == AF_INET) ? ipaddr_ntoa_r((src),(dst),(size)) : NULL) -#define inet_pton(af,src,dst) \ - (((af) == AF_INET) ? inet_aton((src),(dst)) : 0) -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_COMPAT_SOCKETS */ - -#ifdef __cplusplus -} -#endif - -#include "multi-threads/sockets_mt.h" - -#endif /* LWIP_SOCKET */ - -#endif /* __LWIP_SOCKETS_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + +#ifndef __LWIP_SOCKETS_H__ +#define __LWIP_SOCKETS_H__ + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/ip_addr.h" +#include "lwip/inet.h" +#include "lwip/inet6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED) +typedef u8_t sa_family_t; +#endif +/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED) +typedef u16_t in_port_t; +#endif + +/* members are in network byte order */ +struct sockaddr_in { + u8_t sin_len; + sa_family_t sin_family; + in_port_t sin_port; + struct in_addr sin_addr; +#define SIN_ZERO_LEN 8 + char sin_zero[SIN_ZERO_LEN]; +}; + +#if LWIP_IPV6 + +#define INET6_ADDRSTRLEN 46 + +struct sockaddr_in6 { + u8_t sin6_len; /* length of this structure */ + sa_family_t sin6_family; /* AF_INET6 */ + in_port_t sin6_port; /* Transport layer port # */ + u32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ +}; +#endif /* LWIP_IPV6 */ + +struct sockaddr { + u8_t sa_len; + sa_family_t sa_family; +#if LWIP_IPV6 + char sa_data[22]; +#else /* LWIP_IPV6 */ + char sa_data[14]; +#endif /* LWIP_IPV6 */ +}; + +struct sockaddr_storage { + u8_t s2_len; + sa_family_t ss_family; + char s2_data1[2]; + u32_t s2_data2[3]; +#if LWIP_IPV6 + u32_t s2_data3[2]; +#endif /* LWIP_IPV6 */ +}; + +/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) +typedef u32_t socklen_t; +#endif + +/* Socket protocol types (TCP/UDP/RAW) */ +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 +#define SOCK_RAW 3 + +/* + * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) + */ +#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ +#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ +#define SO_REUSEADDR 0x0004 /* Allow local address reuse */ +#define SO_KEEPALIVE 0x0008 /* keep connections alive */ +#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ +#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ +#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ +#define SO_LINGER 0x0080 /* linger on close if data present */ +#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ +#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */ + +#define SO_DONTLINGER ((int)(~SO_LINGER)) + +/* + * Additional options, not kept in so_options. + */ +#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ +#define SO_RCVBUF 0x1002 /* receive buffer size */ +#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* Unimplemented: send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_TYPE 0x1008 /* get socket type */ +#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ +#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ + + +/* + * Structure used for manipulating linger option. + */ +struct linger { + int l_onoff; /* option on/off */ + int l_linger; /* linger time */ +}; + +/* + * Level number for (get/set)sockopt() to apply to socket itself. + */ +#define SOL_SOCKET 0xfff /* options for socket level */ + + +#define AF_UNSPEC 0 +#define AF_INET 2 +#if LWIP_IPV6 +#define AF_INET6 10 +#else /* LWIP_IPV6 */ +#define AF_INET6 AF_UNSPEC +#endif /* LWIP_IPV6 */ +#define PF_INET AF_INET +#define PF_INET6 AF_INET6 +#define PF_UNSPEC AF_UNSPEC + +#define IPPROTO_IP 0 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 +#if LWIP_IPV6 +#define IPPROTO_IPV6 41 +#endif /* LWIP_IPV6 */ +#define IPPROTO_UDPLITE 136 + +/* Flags we can use with send and recv. */ +#define MSG_PEEK 0x01 /* Peeks at an incoming message */ +#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ +#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ +#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ +#define MSG_MORE 0x10 /* Sender will send more */ + + +/* + * Options for level IPPROTO_IP + */ +#define IP_TOS 1 +#define IP_TTL 2 + +#if LWIP_TCP +/* + * Options for level IPPROTO_TCP + */ +#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ +#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */ +#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */ +#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */ +#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */ +#endif /* LWIP_TCP */ + +#if LWIP_IPV6 +/* + * Options for level IPPROTO_IPV6 + */ +#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */ +#endif /* LWIP_IPV6 */ + +#if LWIP_UDP && LWIP_UDPLITE +/* + * Options for level IPPROTO_UDPLITE + */ +#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ +#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ +#endif /* LWIP_UDP && LWIP_UDPLITE*/ + + +#if LWIP_IGMP +/* + * Options and types for UDP multicast traffic handling + */ +#define IP_ADD_MEMBERSHIP 3 +#define IP_DROP_MEMBERSHIP 4 +#define IP_MULTICAST_TTL 5 +#define IP_MULTICAST_IF 6 +#define IP_MULTICAST_LOOP 7 + +typedef struct ip_mreq { + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_interface; /* local IP address of interface */ +} ip_mreq; +#endif /* LWIP_IGMP */ + +/* + * The Type of Service provides an indication of the abstract + * parameters of the quality of service desired. These parameters are + * to be used to guide the selection of the actual service parameters + * when transmitting a datagram through a particular network. Several + * networks offer service precedence, which somehow treats high + * precedence traffic as more important than other traffic (generally + * by accepting only traffic above a certain precedence at time of high + * load). The major choice is a three way tradeoff between low-delay, + * high-reliability, and high-throughput. + * The use of the Delay, Throughput, and Reliability indications may + * increase the cost (in some sense) of the service. In many networks + * better performance for one of these parameters is coupled with worse + * performance on another. Except for very unusual cases at most two + * of these three indications should be set. + */ +#define IPTOS_TOS_MASK 0x1E +#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_LOWCOST 0x02 +#define IPTOS_MINCOST IPTOS_LOWCOST + +/* + * The Network Control precedence designation is intended to be used + * within a network only. The actual use and control of that + * designation is up to each network. The Internetwork Control + * designation is intended for use by gateway control originators only. + * If the actual use of these precedence designations is of concern to + * a particular network, it is the responsibility of that network to + * control the access to, and use of, those precedence designations. + */ +#define IPTOS_PREC_MASK 0xe0 +#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 + + +/* + * Commands for ioctlsocket(), taken from the BSD file fcntl.h. + * lwip_ioctl only supports FIONREAD and FIONBIO, for now + * + * Ioctl's have the command encoded in the lower word, + * and the size of any in or out parameters in the upper + * word. The high 2 bits of the upper word are used + * to encode the in/out status of the parameter; for now + * we restrict parameters to at most 128 bytes. + */ +#if !defined(FIONREAD) || !defined(FIONBIO) +#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ +#define IOC_VOID 0x20000000UL /* no parameters */ +#define IOC_OUT 0x40000000UL /* copy out parameters */ +#define IOC_IN 0x80000000UL /* copy in parameters */ +#define IOC_INOUT (IOC_IN|IOC_OUT) + /* 0x20000000 distinguishes new & + old ioctl's */ +#define _IO(x,y) (IOC_VOID|((x)<<8)|(y)) + +#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) + +#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) +#endif /* !defined(FIONREAD) || !defined(FIONBIO) */ + +#ifndef FIONREAD +#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */ +#endif +#ifndef FIONBIO +#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */ +#endif + +/* Socket I/O Controls: unimplemented */ +#ifndef SIOCSHIWAT +#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */ +#endif + +/* commands for fnctl */ +#ifndef F_GETFL +#define F_GETFL 3 +#endif +#ifndef F_SETFL +#define F_SETFL 4 +#endif + +/* File status flags and file access modes for fnctl, + these are bits in an int. */ +#ifndef O_NONBLOCK +#define O_NONBLOCK 1 /* nonblocking I/O */ +#endif +#ifndef O_NDELAY +#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */ +#endif + +#ifndef SHUT_RD + #define SHUT_RD 0 + #define SHUT_WR 1 + #define SHUT_RDWR 2 +#endif + +/* FD_SET used for lwip_select */ +#ifndef FD_SET + #undef FD_SETSIZE + /* Make FD_SETSIZE match NUM_SOCKETS in socket.c */ + #define FD_SETSIZE MEMP_NUM_NETCONN + #define FD_SET(n, p) ((p)->fd_bits[(n)/8] |= (1 << ((n) & 7))) + #define FD_CLR(n, p) ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7))) + #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] & (1 << ((n) & 7))) + #define FD_ZERO(p) memset((void*)(p),0,sizeof(*(p))) + + typedef struct fd_set { + unsigned char fd_bits [(FD_SETSIZE+7)/8]; + } fd_set; + +#endif /* FD_SET */ + +/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided + * by your system, set this to 0 and include in cc.h */ +#ifndef LWIP_TIMEVAL_PRIVATE +#define LWIP_TIMEVAL_PRIVATE 1 +#endif + +#if LWIP_TIMEVAL_PRIVATE +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; +#endif /* LWIP_TIMEVAL_PRIVATE */ + +void lwip_socket_init(void); + +int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_shutdown(int s, int how); +int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); +int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen); +int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); +int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); + + +/** + * set if lwip_close will use 4-handshake to close a tcp connection, + * + * @param req 1 , send rst pkt directly, when call lwip_close(),rather than 4-handshake. + * then all buffed PCB memory resource will be freed immediately + * 0, send Fin flag pkt other than rst pkt when call lwip_close(s) + * @return + */ +void lwip_force_close_set(char req); + +int lwip_close(int s); +int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_listen(int s, int backlog); +int lwip_recv(int s, void *mem, size_t len, int flags); +int lwip_read(int s, void *mem, size_t len); +int lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen); +int lwip_send(int s, const void *dataptr, size_t size, int flags); +int lwip_sendto(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen); +int lwip_socket(int domain, int type, int protocol); +int lwip_write(int s, const void *dataptr, size_t size); +int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout); +int lwip_ioctl(int s, long cmd, void *argp); +int lwip_fcntl(int s, int cmd, int val); + +#if LWIP_COMPAT_SOCKETS && !defined(SOCKETS_MT) +#define accept(a,b,c) lwip_accept(a,b,c) +#define bind(a,b,c) lwip_bind(a,b,c) +#define shutdown(a,b) lwip_shutdown(a,b) +#define closesocket(s) lwip_close(s) +#define connect(a,b,c) lwip_connect(a,b,c) +#define getsockname(a,b,c) lwip_getsockname(a,b,c) +#define getpeername(a,b,c) lwip_getpeername(a,b,c) +#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e) +#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e) +#define listen(a,b) lwip_listen(a,b) +#define recv(a,b,c,d) lwip_recv(a,b,c,d) +#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f) +#define send(a,b,c,d) lwip_send(a,b,c,d) +#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f) +#define socket(a,b,c) lwip_socket(a,b,c) +#define select(a,b,c,d,e) lwip_select(a,b,c,d,e) +#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c) + +#if LWIP_POSIX_SOCKETS_IO_NAMES +#define read(a,b,c) lwip_read(a,b,c) +#define write(a,b,c) lwip_write(a,b,c) +#define close(s) lwip_close(s) +#define fcntl(a,b,c) lwip_fcntl(a,b,c) +#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ + +#if LWIP_IPV6 +#define inet_ntop(af,src,dst,size) \ + (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t *)(src),(dst),(size)) \ + : (((af) == AF_INET) ? ipaddr_ntoa_r((const ip_addr_t *)(src),(dst),(size)) : NULL)) +#define inet_pton(af,src,dst) \ + (((af) == AF_INET6) ? inet6_aton((src),(const ip6_addr_t *)(dst)) \ + : (((af) == AF_INET) ? inet_aton((src),(const ip_addr_t *)(dst)) : 0)) +#else /* LWIP_IPV6 */ +#define inet_ntop(af,src,dst,size) \ + (((af) == AF_INET) ? ipaddr_ntoa_r((src),(dst),(size)) : NULL) +#define inet_pton(af,src,dst) \ + (((af) == AF_INET) ? inet_aton((src),(dst)) : 0) +#endif /* LWIP_IPV6 */ + +#endif /* LWIP_COMPAT_SOCKETS */ + +#ifdef __cplusplus +} +#endif + +#include "multi-threads/sockets_mt.h" + +#endif /* LWIP_SOCKET */ + +#endif /* __LWIP_SOCKETS_H__ */ diff --git a/include/lwip/lwip/stats.h b/include/lwip/lwip/stats.h index 07df9f62..d9112160 100644 --- a/include/lwip/lwip/stats.h +++ b/include/lwip/lwip/stats.h @@ -1,347 +1,347 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_STATS_H__ -#define __LWIP_STATS_H__ - -#include "lwip/opt.h" - -#include "lwip/mem.h" -#include "lwip/memp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_STATS - -#ifndef LWIP_STATS_LARGE -#define LWIP_STATS_LARGE 0 -#endif - -#if LWIP_STATS_LARGE -#define STAT_COUNTER u32_t -#define STAT_COUNTER_F U32_F -#else -#define STAT_COUNTER u16_t -#define STAT_COUNTER_F U16_F -#endif - -struct stats_proto { - STAT_COUNTER xmit; /* Transmitted packets. */ - STAT_COUNTER recv; /* Received packets. */ - STAT_COUNTER fw; /* Forwarded packets. */ - STAT_COUNTER drop; /* Dropped packets. */ - STAT_COUNTER chkerr; /* Checksum error. */ - STAT_COUNTER lenerr; /* Invalid length error. */ - STAT_COUNTER memerr; /* Out of memory error. */ - STAT_COUNTER rterr; /* Routing error. */ - STAT_COUNTER proterr; /* Protocol error. */ - STAT_COUNTER opterr; /* Error in options. */ - STAT_COUNTER err; /* Misc error. */ - STAT_COUNTER cachehit; -}; - -struct stats_igmp { - STAT_COUNTER xmit; /* Transmitted packets. */ - STAT_COUNTER recv; /* Received packets. */ - STAT_COUNTER drop; /* Dropped packets. */ - STAT_COUNTER chkerr; /* Checksum error. */ - STAT_COUNTER lenerr; /* Invalid length error. */ - STAT_COUNTER memerr; /* Out of memory error. */ - STAT_COUNTER proterr; /* Protocol error. */ - STAT_COUNTER rx_v1; /* Received v1 frames. */ - STAT_COUNTER rx_group; /* Received group-specific queries. */ - STAT_COUNTER rx_general; /* Received general queries. */ - STAT_COUNTER rx_report; /* Received reports. */ - STAT_COUNTER tx_join; /* Sent joins. */ - STAT_COUNTER tx_leave; /* Sent leaves. */ - STAT_COUNTER tx_report; /* Sent reports. */ -}; - -struct stats_mem { -#ifdef LWIP_DEBUG - const char *name; -#endif /* LWIP_DEBUG */ - mem_size_t avail; - mem_size_t used; - mem_size_t max; - STAT_COUNTER err; - STAT_COUNTER illegal; -}; - -struct stats_syselem { - STAT_COUNTER used; - STAT_COUNTER max; - STAT_COUNTER err; -}; - -struct stats_sys { - struct stats_syselem sem; - struct stats_syselem mutex; - struct stats_syselem mbox; -}; - -struct stats_ { -#if LINK_STATS - struct stats_proto link; -#endif -#if ETHARP_STATS - struct stats_proto etharp; -#endif -#if IPFRAG_STATS - struct stats_proto ip_frag; -#endif -#if IP_STATS - struct stats_proto ip; -#endif -#if ICMP_STATS - struct stats_proto icmp; -#endif -#if IGMP_STATS - struct stats_igmp igmp; -#endif -#if UDP_STATS - struct stats_proto udp; -#endif -#if TCP_STATS - struct stats_proto tcp; -#endif -#if MEM_STATS - struct stats_mem mem; -#endif -#if MEMP_STATS - struct stats_mem memp[MEMP_MAX]; -#endif -#if SYS_STATS - struct stats_sys sys; -#endif -#if IP6_STATS - struct stats_proto ip6; -#endif -#if ICMP6_STATS - struct stats_proto icmp6; -#endif -#if IP6_FRAG_STATS - struct stats_proto ip6_frag; -#endif -#if MLD6_STATS - struct stats_igmp mld6; -#endif -#if ND6_STATS - struct stats_proto nd6; -#endif -}; - -extern struct stats_ lwip_stats; - -void stats_init(void); - -#define STATS_INC(x) ++lwip_stats.x -#define STATS_DEC(x) --lwip_stats.x -#define STATS_INC_USED(x, y) do { lwip_stats.x.used += y; \ - if (lwip_stats.x.max < lwip_stats.x.used) { \ - lwip_stats.x.max = lwip_stats.x.used; \ - } \ - } while(0) -#else /* LWIP_STATS */ -#define stats_init() -#define STATS_INC(x) -#define STATS_DEC(x) -#define STATS_INC_USED(x) -#endif /* LWIP_STATS */ - -#if TCP_STATS -#define TCP_STATS_INC(x) STATS_INC(x) -#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP") -#else -#define TCP_STATS_INC(x) -#define TCP_STATS_DISPLAY() -#endif - -#if UDP_STATS -#define UDP_STATS_INC(x) STATS_INC(x) -#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP") -#else -#define UDP_STATS_INC(x) -#define UDP_STATS_DISPLAY() -#endif - -#if ICMP_STATS -#define ICMP_STATS_INC(x) STATS_INC(x) -#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP") -#else -#define ICMP_STATS_INC(x) -#define ICMP_STATS_DISPLAY() -#endif - -#if IGMP_STATS -#define IGMP_STATS_INC(x) STATS_INC(x) -#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp, "IGMP") -#else -#define IGMP_STATS_INC(x) -#define IGMP_STATS_DISPLAY() -#endif - -#if IP_STATS -#define IP_STATS_INC(x) STATS_INC(x) -#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP") -#else -#define IP_STATS_INC(x) -#define IP_STATS_DISPLAY() -#endif - -#if IPFRAG_STATS -#define IPFRAG_STATS_INC(x) STATS_INC(x) -#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG") -#else -#define IPFRAG_STATS_INC(x) -#define IPFRAG_STATS_DISPLAY() -#endif - -#if ETHARP_STATS -#define ETHARP_STATS_INC(x) STATS_INC(x) -#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP") -#else -#define ETHARP_STATS_INC(x) -#define ETHARP_STATS_DISPLAY() -#endif - -#if LINK_STATS -#define LINK_STATS_INC(x) STATS_INC(x) -#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK") -#else -#define LINK_STATS_INC(x) -#define LINK_STATS_DISPLAY() -#endif - -#if MEM_STATS -#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y -#define MEM_STATS_INC(x) STATS_INC(mem.x) -#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y) -#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x -= y -#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP") -#else -#define MEM_STATS_AVAIL(x, y) -#define MEM_STATS_INC(x) -#define MEM_STATS_INC_USED(x, y) -#define MEM_STATS_DEC_USED(x, y) -#define MEM_STATS_DISPLAY() -#endif - -#if MEMP_STATS -#define MEMP_STATS_AVAIL(x, i, y) lwip_stats.memp[i].x = y -#define MEMP_STATS_INC(x, i) STATS_INC(memp[i].x) -#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i].x) -#define MEMP_STATS_INC_USED(x, i) STATS_INC_USED(memp[i], 1) -#define MEMP_STATS_DISPLAY(i) stats_display_memp(&lwip_stats.memp[i], i) -#else -#define MEMP_STATS_AVAIL(x, i, y) -#define MEMP_STATS_INC(x, i) -#define MEMP_STATS_DEC(x, i) -#define MEMP_STATS_INC_USED(x, i) -#define MEMP_STATS_DISPLAY(i) -#endif - -#if SYS_STATS -#define SYS_STATS_INC(x) STATS_INC(sys.x) -#define SYS_STATS_DEC(x) STATS_DEC(sys.x) -#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1) -#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys) -#else -#define SYS_STATS_INC(x) -#define SYS_STATS_DEC(x) -#define SYS_STATS_INC_USED(x) -#define SYS_STATS_DISPLAY() -#endif - -#if IP6_STATS -#define IP6_STATS_INC(x) STATS_INC(x) -#define IP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6, "IPv6") -#else -#define IP6_STATS_INC(x) -#define IP6_STATS_DISPLAY() -#endif - -#if ICMP6_STATS -#define ICMP6_STATS_INC(x) STATS_INC(x) -#define ICMP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp6, "ICMPv6") -#else -#define ICMP6_STATS_INC(x) -#define ICMP6_STATS_DISPLAY() -#endif - -#if IP6_FRAG_STATS -#define IP6_FRAG_STATS_INC(x) STATS_INC(x) -#define IP6_FRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6_frag, "IPv6 FRAG") -#else -#define IP6_FRAG_STATS_INC(x) -#define IP6_FRAG_STATS_DISPLAY() -#endif - -#if MLD6_STATS -#define MLD6_STATS_INC(x) STATS_INC(x) -#define MLD6_STATS_DISPLAY() stats_display_igmp(&lwip_stats.mld6, "MLDv1") -#else -#define MLD6_STATS_INC(x) -#define MLD6_STATS_DISPLAY() -#endif - -#if ND6_STATS -#define ND6_STATS_INC(x) STATS_INC(x) -#define ND6_STATS_DISPLAY() stats_display_proto(&lwip_stats.nd6, "ND") -#else -#define ND6_STATS_INC(x) -#define ND6_STATS_DISPLAY() -#endif - -/* Display of statistics */ -#if LWIP_STATS_DISPLAY -void stats_display(void); -void stats_display_proto(struct stats_proto *proto, const char *name); -void stats_display_igmp(struct stats_igmp *igmp, const char *name); -void stats_display_mem(struct stats_mem *mem, const char *name); -void stats_display_memp(struct stats_mem *mem, int index); -void stats_display_sys(struct stats_sys *sys); -#else /* LWIP_STATS_DISPLAY */ -#define stats_display() -#define stats_display_proto(proto, name) -#define stats_display_igmp(igmp, name) -#define stats_display_mem(mem, name) -#define stats_display_memp(mem, index) -#define stats_display_sys(sys) -#endif /* LWIP_STATS_DISPLAY */ - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_STATS_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_STATS_H__ +#define __LWIP_STATS_H__ + +#include "lwip/opt.h" + +#include "lwip/mem.h" +#include "lwip/memp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_STATS + +#ifndef LWIP_STATS_LARGE +#define LWIP_STATS_LARGE 0 +#endif + +#if LWIP_STATS_LARGE +#define STAT_COUNTER u32_t +#define STAT_COUNTER_F U32_F +#else +#define STAT_COUNTER u16_t +#define STAT_COUNTER_F U16_F +#endif + +struct stats_proto { + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ + STAT_COUNTER fw; /* Forwarded packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER memerr; /* Out of memory error. */ + STAT_COUNTER rterr; /* Routing error. */ + STAT_COUNTER proterr; /* Protocol error. */ + STAT_COUNTER opterr; /* Error in options. */ + STAT_COUNTER err; /* Misc error. */ + STAT_COUNTER cachehit; +}; + +struct stats_igmp { + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER memerr; /* Out of memory error. */ + STAT_COUNTER proterr; /* Protocol error. */ + STAT_COUNTER rx_v1; /* Received v1 frames. */ + STAT_COUNTER rx_group; /* Received group-specific queries. */ + STAT_COUNTER rx_general; /* Received general queries. */ + STAT_COUNTER rx_report; /* Received reports. */ + STAT_COUNTER tx_join; /* Sent joins. */ + STAT_COUNTER tx_leave; /* Sent leaves. */ + STAT_COUNTER tx_report; /* Sent reports. */ +}; + +struct stats_mem { +#ifdef LWIP_DEBUG + const char *name; +#endif /* LWIP_DEBUG */ + mem_size_t avail; + mem_size_t used; + mem_size_t max; + STAT_COUNTER err; + STAT_COUNTER illegal; +}; + +struct stats_syselem { + STAT_COUNTER used; + STAT_COUNTER max; + STAT_COUNTER err; +}; + +struct stats_sys { + struct stats_syselem sem; + struct stats_syselem mutex; + struct stats_syselem mbox; +}; + +struct stats_ { +#if LINK_STATS + struct stats_proto link; +#endif +#if ETHARP_STATS + struct stats_proto etharp; +#endif +#if IPFRAG_STATS + struct stats_proto ip_frag; +#endif +#if IP_STATS + struct stats_proto ip; +#endif +#if ICMP_STATS + struct stats_proto icmp; +#endif +#if IGMP_STATS + struct stats_igmp igmp; +#endif +#if UDP_STATS + struct stats_proto udp; +#endif +#if TCP_STATS + struct stats_proto tcp; +#endif +#if MEM_STATS + struct stats_mem mem; +#endif +#if MEMP_STATS + struct stats_mem memp[MEMP_MAX]; +#endif +#if SYS_STATS + struct stats_sys sys; +#endif +#if IP6_STATS + struct stats_proto ip6; +#endif +#if ICMP6_STATS + struct stats_proto icmp6; +#endif +#if IP6_FRAG_STATS + struct stats_proto ip6_frag; +#endif +#if MLD6_STATS + struct stats_igmp mld6; +#endif +#if ND6_STATS + struct stats_proto nd6; +#endif +}; + +extern struct stats_ lwip_stats; + +void stats_init(void); + +#define STATS_INC(x) ++lwip_stats.x +#define STATS_DEC(x) --lwip_stats.x +#define STATS_INC_USED(x, y) do { lwip_stats.x.used += y; \ + if (lwip_stats.x.max < lwip_stats.x.used) { \ + lwip_stats.x.max = lwip_stats.x.used; \ + } \ + } while(0) +#else /* LWIP_STATS */ +#define stats_init() +#define STATS_INC(x) +#define STATS_DEC(x) +#define STATS_INC_USED(x) +#endif /* LWIP_STATS */ + +#if TCP_STATS +#define TCP_STATS_INC(x) STATS_INC(x) +#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP") +#else +#define TCP_STATS_INC(x) +#define TCP_STATS_DISPLAY() +#endif + +#if UDP_STATS +#define UDP_STATS_INC(x) STATS_INC(x) +#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP") +#else +#define UDP_STATS_INC(x) +#define UDP_STATS_DISPLAY() +#endif + +#if ICMP_STATS +#define ICMP_STATS_INC(x) STATS_INC(x) +#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP") +#else +#define ICMP_STATS_INC(x) +#define ICMP_STATS_DISPLAY() +#endif + +#if IGMP_STATS +#define IGMP_STATS_INC(x) STATS_INC(x) +#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp, "IGMP") +#else +#define IGMP_STATS_INC(x) +#define IGMP_STATS_DISPLAY() +#endif + +#if IP_STATS +#define IP_STATS_INC(x) STATS_INC(x) +#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP") +#else +#define IP_STATS_INC(x) +#define IP_STATS_DISPLAY() +#endif + +#if IPFRAG_STATS +#define IPFRAG_STATS_INC(x) STATS_INC(x) +#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG") +#else +#define IPFRAG_STATS_INC(x) +#define IPFRAG_STATS_DISPLAY() +#endif + +#if ETHARP_STATS +#define ETHARP_STATS_INC(x) STATS_INC(x) +#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP") +#else +#define ETHARP_STATS_INC(x) +#define ETHARP_STATS_DISPLAY() +#endif + +#if LINK_STATS +#define LINK_STATS_INC(x) STATS_INC(x) +#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK") +#else +#define LINK_STATS_INC(x) +#define LINK_STATS_DISPLAY() +#endif + +#if MEM_STATS +#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y +#define MEM_STATS_INC(x) STATS_INC(mem.x) +#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y) +#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x -= y +#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP") +#else +#define MEM_STATS_AVAIL(x, y) +#define MEM_STATS_INC(x) +#define MEM_STATS_INC_USED(x, y) +#define MEM_STATS_DEC_USED(x, y) +#define MEM_STATS_DISPLAY() +#endif + +#if MEMP_STATS +#define MEMP_STATS_AVAIL(x, i, y) lwip_stats.memp[i].x = y +#define MEMP_STATS_INC(x, i) STATS_INC(memp[i].x) +#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i].x) +#define MEMP_STATS_INC_USED(x, i) STATS_INC_USED(memp[i], 1) +#define MEMP_STATS_DISPLAY(i) stats_display_memp(&lwip_stats.memp[i], i) +#else +#define MEMP_STATS_AVAIL(x, i, y) +#define MEMP_STATS_INC(x, i) +#define MEMP_STATS_DEC(x, i) +#define MEMP_STATS_INC_USED(x, i) +#define MEMP_STATS_DISPLAY(i) +#endif + +#if SYS_STATS +#define SYS_STATS_INC(x) STATS_INC(sys.x) +#define SYS_STATS_DEC(x) STATS_DEC(sys.x) +#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1) +#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys) +#else +#define SYS_STATS_INC(x) +#define SYS_STATS_DEC(x) +#define SYS_STATS_INC_USED(x) +#define SYS_STATS_DISPLAY() +#endif + +#if IP6_STATS +#define IP6_STATS_INC(x) STATS_INC(x) +#define IP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6, "IPv6") +#else +#define IP6_STATS_INC(x) +#define IP6_STATS_DISPLAY() +#endif + +#if ICMP6_STATS +#define ICMP6_STATS_INC(x) STATS_INC(x) +#define ICMP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp6, "ICMPv6") +#else +#define ICMP6_STATS_INC(x) +#define ICMP6_STATS_DISPLAY() +#endif + +#if IP6_FRAG_STATS +#define IP6_FRAG_STATS_INC(x) STATS_INC(x) +#define IP6_FRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6_frag, "IPv6 FRAG") +#else +#define IP6_FRAG_STATS_INC(x) +#define IP6_FRAG_STATS_DISPLAY() +#endif + +#if MLD6_STATS +#define MLD6_STATS_INC(x) STATS_INC(x) +#define MLD6_STATS_DISPLAY() stats_display_igmp(&lwip_stats.mld6, "MLDv1") +#else +#define MLD6_STATS_INC(x) +#define MLD6_STATS_DISPLAY() +#endif + +#if ND6_STATS +#define ND6_STATS_INC(x) STATS_INC(x) +#define ND6_STATS_DISPLAY() stats_display_proto(&lwip_stats.nd6, "ND") +#else +#define ND6_STATS_INC(x) +#define ND6_STATS_DISPLAY() +#endif + +/* Display of statistics */ +#if LWIP_STATS_DISPLAY +void stats_display(void); +void stats_display_proto(struct stats_proto *proto, const char *name); +void stats_display_igmp(struct stats_igmp *igmp, const char *name); +void stats_display_mem(struct stats_mem *mem, const char *name); +void stats_display_memp(struct stats_mem *mem, int index); +void stats_display_sys(struct stats_sys *sys); +#else /* LWIP_STATS_DISPLAY */ +#define stats_display() +#define stats_display_proto(proto, name) +#define stats_display_igmp(igmp, name) +#define stats_display_mem(mem, name) +#define stats_display_memp(mem, index) +#define stats_display_sys(sys) +#endif /* LWIP_STATS_DISPLAY */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_STATS_H__ */ diff --git a/include/lwip/lwip/sys.h b/include/lwip/lwip/sys.h index d831f4c3..fd45ee8a 100644 --- a/include/lwip/lwip/sys.h +++ b/include/lwip/lwip/sys.h @@ -1,336 +1,336 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_SYS_H__ -#define __LWIP_SYS_H__ - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if NO_SYS - -/* For a totally minimal and standalone system, we provide null - definitions of the sys_ functions. */ -typedef u8_t sys_sem_t; -typedef u8_t sys_mutex_t; -typedef u8_t sys_mbox_t; - -#define sys_sem_new(s, c) ERR_OK -#define sys_sem_signal(s) -#define sys_sem_wait(s) -#define sys_arch_sem_wait(s,t) -#define sys_sem_free(s) -#define sys_sem_valid(s) 0 -#define sys_sem_set_invalid(s) -#define sys_mutex_new(mu) ERR_OK -#define sys_mutex_lock(mu) -#define sys_mutex_unlock(mu) -#define sys_mutex_free(mu) -#define sys_mutex_valid(mu) 0 -#define sys_mutex_set_invalid(mu) -#define sys_mbox_new(m, s) ERR_OK -#define sys_mbox_fetch(m,d) -#define sys_mbox_tryfetch(m,d) -#define sys_mbox_post(m,d) -#define sys_mbox_trypost(m,d) -#define sys_mbox_free(m) -#define sys_mbox_valid(m) -#define sys_mbox_set_invalid(m) - -#define sys_thread_new(n,t,a,s,p) - -#define sys_msleep(t) - -#else /* NO_SYS */ - -/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ -#define SYS_ARCH_TIMEOUT 0xffffffffUL - -/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. - * For now we use the same magic value, but we allow this to change in future. - */ -#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT - -#include "lwip/err.h" -#include "arch/sys_arch.h" - -/** Function prototype for thread functions */ -typedef void (*lwip_thread_fn)(void *arg); - -/* Function prototypes for functions to be implemented by platform ports - (in sys_arch.c) */ - -/* Mutex functions: */ - -/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores - should be used instead */ -#if LWIP_COMPAT_MUTEX -/* for old ports that don't have mutexes: define them to binary semaphores */ -#define sys_mutex_t sys_sem_t -#define sys_mutex_new(mutex) sys_sem_new(mutex, 1) -#define sys_mutex_lock(mutex) sys_sem_wait(mutex) -#define sys_mutex_unlock(mutex) sys_sem_signal(mutex) -#define sys_mutex_free(mutex) sys_sem_free(mutex) -#define sys_mutex_valid(mutex) sys_sem_valid(mutex) -#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) - -#else /* LWIP_COMPAT_MUTEX */ - -/** Create a new mutex - * @param mutex pointer to the mutex to create - * @return a new mutex */ -err_t sys_mutex_new(sys_mutex_t *mutex); -/** Lock a mutex - * @param mutex the mutex to lock */ -void sys_mutex_lock(sys_mutex_t *mutex); -/** Unlock a mutex - * @param mutex the mutex to unlock */ -void sys_mutex_unlock(sys_mutex_t *mutex); -/** Delete a semaphore - * @param mutex the mutex to delete */ -void sys_mutex_free(sys_mutex_t *mutex); -#ifndef sys_mutex_valid -/** Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid */ -int sys_mutex_valid(sys_mutex_t *mutex); -#endif -#ifndef sys_mutex_set_invalid -/** Set a mutex invalid so that sys_mutex_valid returns 0 */ -void sys_mutex_set_invalid(sys_mutex_t *mutex); -#endif -#endif /* LWIP_COMPAT_MUTEX */ - -/* Semaphore functions: */ - -/** Create a new semaphore - * @param sem pointer to the semaphore to create - * @param count initial count of the semaphore - * @return ERR_OK if successful, another err_t otherwise */ -err_t sys_sem_new(sys_sem_t *sem, u8_t count); -/** Signals a semaphore - * @param sem the semaphore to signal */ -void sys_sem_signal(sys_sem_t *sem); -/** Wait for a semaphore for the specified timeout - * @param sem the semaphore to wait for - * @param timeout timeout in milliseconds to wait (0 = wait forever) - * @return time (in milliseconds) waited for the semaphore - * or SYS_ARCH_TIMEOUT on timeout */ -u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout); -/** Delete a semaphore - * @param sem semaphore to delete */ -void sys_sem_free(sys_sem_t *sem); -/** Wait for a semaphore - forever/no timeout */ -#define sys_sem_wait(sem) sys_arch_sem_wait(sem, 0) -#ifndef sys_sem_valid -/** Check if a sempahore is valid/allocated: return 1 for valid, 0 for invalid */ -int sys_sem_valid(sys_sem_t *sem); -#endif -#ifndef sys_sem_set_invalid -/** Set a semaphore invalid so that sys_sem_valid returns 0 */ -void sys_sem_set_invalid(sys_sem_t *sem); -#endif - -/* Time functions. */ -#ifndef sys_msleep -void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */ -#endif - -/* Mailbox functions. */ - -/** Create a new mbox of specified size - * @param mbox pointer to the mbox to create - * @param size (miminum) number of messages in this mbox - * @return ERR_OK if successful, another err_t otherwise */ -err_t sys_mbox_new(sys_mbox_t *mbox, int size); -/** Post a message to an mbox - may not fail - * -> blocks if full, only used from tasks not from ISR - * @param mbox mbox to posts the message - * @param msg message to post (ATTENTION: can be NULL) */ -void sys_mbox_post(sys_mbox_t *mbox, void *msg); -/** Try to post a message to an mbox - may fail if full or ISR - * @param mbox mbox to posts the message - * @param msg message to post (ATTENTION: can be NULL) */ -err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); -/** Wait for a new message to arrive in the mbox - * @param mbox mbox to get a message from - * @param msg pointer where the message is stored - * @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever) - * @return time (in milliseconds) waited for a message, may be 0 if not waited - or SYS_ARCH_TIMEOUT on timeout - * The returned time has to be accurate to prevent timer jitter! */ -u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); -/* Allow port to override with a macro, e.g. special timout for sys_arch_mbox_fetch() */ -#ifndef sys_arch_mbox_tryfetch -/** Wait for a new message to arrive in the mbox - * @param mbox mbox to get a message from - * @param msg pointer where the message is stored - * @return 0 (milliseconds) if a message has been received - * or SYS_MBOX_EMPTY if the mailbox is empty */ -u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg); -#endif -/** For now, we map straight to sys_arch implementation. */ -#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) -/** Delete an mbox - * @param mbox mbox to delete */ -void sys_mbox_free(sys_mbox_t *mbox); -#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) -#ifndef sys_mbox_valid -/** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */ -int sys_mbox_valid(sys_mbox_t *mbox); -#endif -#ifndef sys_mbox_set_invalid -/** Set an mbox invalid so that sys_mbox_valid returns 0 */ -void sys_mbox_set_invalid(sys_mbox_t *mbox); -#endif - -/** The only thread function: - * Creates a new thread - * @param name human-readable name for the thread (used for debugging purposes) - * @param thread thread-function - * @param arg parameter passed to 'thread' - * @param stacksize stack size in bytes for the new thread (may be ignored by ports) - * @param prio priority of the new thread (may be ignored by ports) */ -sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio); - -#endif /* NO_SYS */ - -/* sys_init() must be called before anthing else. */ -void sys_init(void); - -#ifndef sys_jiffies -/** Ticks/jiffies since power up. */ -u32_t sys_jiffies(void); -#endif - -/** Returns the current time in milliseconds, - * may be the same as sys_jiffies or at least based on it. */ -u32_t sys_now(void); - -/* Critical Region Protection */ -/* These functions must be implemented in the sys_arch.c file. - In some implementations they can provide a more light-weight protection - mechanism than using semaphores. Otherwise semaphores can be used for - implementation */ -#ifndef SYS_ARCH_PROTECT -/** SYS_LIGHTWEIGHT_PROT - * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection - * for certain critical regions during buffer allocation, deallocation and memory - * allocation and deallocation. - */ -#if SYS_LIGHTWEIGHT_PROT - -/** SYS_ARCH_DECL_PROTECT - * declare a protection variable. This macro will default to defining a variable of - * type sys_prot_t. If a particular port needs a different implementation, then - * this macro may be defined in sys_arch.h. - */ -#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev -/** SYS_ARCH_PROTECT - * Perform a "fast" protect. This could be implemented by - * disabling interrupts for an embedded system or by using a semaphore or - * mutex. The implementation should allow calling SYS_ARCH_PROTECT when - * already protected. The old protection level is returned in the variable - * "lev". This macro will default to calling the sys_arch_protect() function - * which should be implemented in sys_arch.c. If a particular port needs a - * different implementation, then this macro may be defined in sys_arch.h - */ -#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() -/** SYS_ARCH_UNPROTECT - * Perform a "fast" set of the protection level to "lev". This could be - * implemented by setting the interrupt level to "lev" within the MACRO or by - * using a semaphore or mutex. This macro will default to calling the - * sys_arch_unprotect() function which should be implemented in - * sys_arch.c. If a particular port needs a different implementation, then - * this macro may be defined in sys_arch.h - */ -#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) -sys_prot_t sys_arch_protect(void); -void sys_arch_unprotect(sys_prot_t pval); - -#else - -#define SYS_ARCH_DECL_PROTECT(lev) -#define SYS_ARCH_PROTECT(lev) -#define SYS_ARCH_UNPROTECT(lev) - -#endif /* SYS_LIGHTWEIGHT_PROT */ - -#endif /* SYS_ARCH_PROTECT */ - -/* - * Macros to set/get and increase/decrease variables in a thread-safe way. - * Use these for accessing variable that are used from more than one thread. - */ - -#ifndef SYS_ARCH_INC -#define SYS_ARCH_INC(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var += val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_INC */ - -#ifndef SYS_ARCH_DEC -#define SYS_ARCH_DEC(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var -= val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_DEC */ - -#ifndef SYS_ARCH_GET -#define SYS_ARCH_GET(var, ret) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - ret = var; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_GET */ - -#ifndef SYS_ARCH_SET -#define SYS_ARCH_SET(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var = val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_SET */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __LWIP_SYS_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_SYS_H__ +#define __LWIP_SYS_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if NO_SYS + +/* For a totally minimal and standalone system, we provide null + definitions of the sys_ functions. */ +typedef u8_t sys_sem_t; +typedef u8_t sys_mutex_t; +typedef u8_t sys_mbox_t; + +#define sys_sem_new(s, c) ERR_OK +#define sys_sem_signal(s) +#define sys_sem_wait(s) +#define sys_arch_sem_wait(s,t) +#define sys_sem_free(s) +#define sys_sem_valid(s) 0 +#define sys_sem_set_invalid(s) +#define sys_mutex_new(mu) ERR_OK +#define sys_mutex_lock(mu) +#define sys_mutex_unlock(mu) +#define sys_mutex_free(mu) +#define sys_mutex_valid(mu) 0 +#define sys_mutex_set_invalid(mu) +#define sys_mbox_new(m, s) ERR_OK +#define sys_mbox_fetch(m,d) +#define sys_mbox_tryfetch(m,d) +#define sys_mbox_post(m,d) +#define sys_mbox_trypost(m,d) +#define sys_mbox_free(m) +#define sys_mbox_valid(m) +#define sys_mbox_set_invalid(m) + +#define sys_thread_new(n,t,a,s,p) + +#define sys_msleep(t) + +#else /* NO_SYS */ + +/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ +#define SYS_ARCH_TIMEOUT 0xffffffffUL + +/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. + * For now we use the same magic value, but we allow this to change in future. + */ +#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT + +#include "lwip/err.h" +#include "arch/sys_arch.h" + +/** Function prototype for thread functions */ +typedef void (*lwip_thread_fn)(void *arg); + +/* Function prototypes for functions to be implemented by platform ports + (in sys_arch.c) */ + +/* Mutex functions: */ + +/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores + should be used instead */ +#if LWIP_COMPAT_MUTEX +/* for old ports that don't have mutexes: define them to binary semaphores */ +#define sys_mutex_t sys_sem_t +#define sys_mutex_new(mutex) sys_sem_new(mutex, 1) +#define sys_mutex_lock(mutex) sys_sem_wait(mutex) +#define sys_mutex_unlock(mutex) sys_sem_signal(mutex) +#define sys_mutex_free(mutex) sys_sem_free(mutex) +#define sys_mutex_valid(mutex) sys_sem_valid(mutex) +#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) + +#else /* LWIP_COMPAT_MUTEX */ + +/** Create a new mutex + * @param mutex pointer to the mutex to create + * @return a new mutex */ +err_t sys_mutex_new(sys_mutex_t *mutex); +/** Lock a mutex + * @param mutex the mutex to lock */ +void sys_mutex_lock(sys_mutex_t *mutex); +/** Unlock a mutex + * @param mutex the mutex to unlock */ +void sys_mutex_unlock(sys_mutex_t *mutex); +/** Delete a semaphore + * @param mutex the mutex to delete */ +void sys_mutex_free(sys_mutex_t *mutex); +#ifndef sys_mutex_valid +/** Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_mutex_valid(sys_mutex_t *mutex); +#endif +#ifndef sys_mutex_set_invalid +/** Set a mutex invalid so that sys_mutex_valid returns 0 */ +void sys_mutex_set_invalid(sys_mutex_t *mutex); +#endif +#endif /* LWIP_COMPAT_MUTEX */ + +/* Semaphore functions: */ + +/** Create a new semaphore + * @param sem pointer to the semaphore to create + * @param count initial count of the semaphore + * @return ERR_OK if successful, another err_t otherwise */ +err_t sys_sem_new(sys_sem_t *sem, u8_t count); +/** Signals a semaphore + * @param sem the semaphore to signal */ +void sys_sem_signal(sys_sem_t *sem); +/** Wait for a semaphore for the specified timeout + * @param sem the semaphore to wait for + * @param timeout timeout in milliseconds to wait (0 = wait forever) + * @return time (in milliseconds) waited for the semaphore + * or SYS_ARCH_TIMEOUT on timeout */ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout); +/** Delete a semaphore + * @param sem semaphore to delete */ +void sys_sem_free(sys_sem_t *sem); +/** Wait for a semaphore - forever/no timeout */ +#define sys_sem_wait(sem) sys_arch_sem_wait(sem, 0) +#ifndef sys_sem_valid +/** Check if a sempahore is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_sem_valid(sys_sem_t *sem); +#endif +#ifndef sys_sem_set_invalid +/** Set a semaphore invalid so that sys_sem_valid returns 0 */ +void sys_sem_set_invalid(sys_sem_t *sem); +#endif + +/* Time functions. */ +#ifndef sys_msleep +void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */ +#endif + +/* Mailbox functions. */ + +/** Create a new mbox of specified size + * @param mbox pointer to the mbox to create + * @param size (miminum) number of messages in this mbox + * @return ERR_OK if successful, another err_t otherwise */ +err_t sys_mbox_new(sys_mbox_t *mbox, int size); +/** Post a message to an mbox - may not fail + * -> blocks if full, only used from tasks not from ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) */ +void sys_mbox_post(sys_mbox_t *mbox, void *msg); +/** Try to post a message to an mbox - may fail if full or ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) */ +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); +/** Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever) + * @return time (in milliseconds) waited for a message, may be 0 if not waited + or SYS_ARCH_TIMEOUT on timeout + * The returned time has to be accurate to prevent timer jitter! */ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); +/* Allow port to override with a macro, e.g. special timout for sys_arch_mbox_fetch() */ +#ifndef sys_arch_mbox_tryfetch +/** Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @return 0 (milliseconds) if a message has been received + * or SYS_MBOX_EMPTY if the mailbox is empty */ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg); +#endif +/** For now, we map straight to sys_arch implementation. */ +#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) +/** Delete an mbox + * @param mbox mbox to delete */ +void sys_mbox_free(sys_mbox_t *mbox); +#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) +#ifndef sys_mbox_valid +/** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_mbox_valid(sys_mbox_t *mbox); +#endif +#ifndef sys_mbox_set_invalid +/** Set an mbox invalid so that sys_mbox_valid returns 0 */ +void sys_mbox_set_invalid(sys_mbox_t *mbox); +#endif + +/** The only thread function: + * Creates a new thread + * @param name human-readable name for the thread (used for debugging purposes) + * @param thread thread-function + * @param arg parameter passed to 'thread' + * @param stacksize stack size in bytes for the new thread (may be ignored by ports) + * @param prio priority of the new thread (may be ignored by ports) */ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio); + +#endif /* NO_SYS */ + +/* sys_init() must be called before anthing else. */ +void sys_init(void); + +#ifndef sys_jiffies +/** Ticks/jiffies since power up. */ +u32_t sys_jiffies(void); +#endif + +/** Returns the current time in milliseconds, + * may be the same as sys_jiffies or at least based on it. */ +u32_t sys_now(void); + +/* Critical Region Protection */ +/* These functions must be implemented in the sys_arch.c file. + In some implementations they can provide a more light-weight protection + mechanism than using semaphores. Otherwise semaphores can be used for + implementation */ +#ifndef SYS_ARCH_PROTECT +/** SYS_LIGHTWEIGHT_PROT + * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection + * for certain critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#if SYS_LIGHTWEIGHT_PROT + +/** SYS_ARCH_DECL_PROTECT + * declare a protection variable. This macro will default to defining a variable of + * type sys_prot_t. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h. + */ +#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev +/** SYS_ARCH_PROTECT + * Perform a "fast" protect. This could be implemented by + * disabling interrupts for an embedded system or by using a semaphore or + * mutex. The implementation should allow calling SYS_ARCH_PROTECT when + * already protected. The old protection level is returned in the variable + * "lev". This macro will default to calling the sys_arch_protect() function + * which should be implemented in sys_arch.c. If a particular port needs a + * different implementation, then this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() +/** SYS_ARCH_UNPROTECT + * Perform a "fast" set of the protection level to "lev". This could be + * implemented by setting the interrupt level to "lev" within the MACRO or by + * using a semaphore or mutex. This macro will default to calling the + * sys_arch_unprotect() function which should be implemented in + * sys_arch.c. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) +sys_prot_t sys_arch_protect(void); +void sys_arch_unprotect(sys_prot_t pval); + +#else + +#define SYS_ARCH_DECL_PROTECT(lev) +#define SYS_ARCH_PROTECT(lev) +#define SYS_ARCH_UNPROTECT(lev) + +#endif /* SYS_LIGHTWEIGHT_PROT */ + +#endif /* SYS_ARCH_PROTECT */ + +/* + * Macros to set/get and increase/decrease variables in a thread-safe way. + * Use these for accessing variable that are used from more than one thread. + */ + +#ifndef SYS_ARCH_INC +#define SYS_ARCH_INC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var += val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_INC */ + +#ifndef SYS_ARCH_DEC +#define SYS_ARCH_DEC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var -= val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_DEC */ + +#ifndef SYS_ARCH_GET +#define SYS_ARCH_GET(var, ret) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + ret = var; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_GET */ + +#ifndef SYS_ARCH_SET +#define SYS_ARCH_SET(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var = val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_SET */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_SYS_H__ */ diff --git a/include/lwip/lwip/tcp.h b/include/lwip/lwip/tcp.h index e6d32407..add77e8d 100644 --- a/include/lwip/lwip/tcp.h +++ b/include/lwip/lwip/tcp.h @@ -1,397 +1,397 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_TCP_H__ -#define __LWIP_TCP_H__ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/icmp.h" -#include "lwip/err.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct tcp_pcb; - -/** Function prototype for tcp accept callback functions. Called when a new - * connection can be accepted on a listening pcb. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param newpcb The new connection pcb - * @param err An error code if there has been an error accepting. - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); - -/** Function prototype for tcp receive callback functions. Called when data has - * been received. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb which received data - * @param p The received data (or NULL when the connection has been closed!) - * @param err An error code if there has been an error receiving - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, - struct pbuf *p, err_t err); - -/** Function prototype for tcp sent callback functions. Called when sent data has - * been acknowledged by the remote side. Use it to free corresponding resources. - * This also means that the pcb has now space available to send new data. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb for which data has been acknowledged - * @param len The amount of bytes acknowledged - * @return ERR_OK: try to send some data by calling tcp_output - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, - u16_t len); - -/** Function prototype for tcp poll callback functions. Called periodically as - * specified by @see tcp_poll. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb tcp pcb - * @return ERR_OK: try to send some data by calling tcp_output - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); - -/** Function prototype for tcp error callback functions. Called when the pcb - * receives a RST or is unexpectedly closed for any other reason. - * - * @note The corresponding pcb is already freed when this callback is called! - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param err Error code to indicate why the pcb has been closed - * ERR_ABRT: aborted through tcp_abort or by a TCP timer - * ERR_RST: the connection was reset by the remote host - */ -typedef void (*tcp_err_fn)(void *arg, err_t err); - -/** Function prototype for tcp connected callback functions. Called when a pcb - * is connected to the remote side after initiating a connection attempt by - * calling tcp_connect(). - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb which is connected - * @param err An unused error code, always ERR_OK currently ;-) TODO! - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - * - * @note When a connection attempt fails, the error callback is currently called! - */ -typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); - -enum tcp_state { - CLOSED = 0, - LISTEN = 1, - SYN_SENT = 2, - SYN_RCVD = 3, - ESTABLISHED = 4, - FIN_WAIT_1 = 5, - FIN_WAIT_2 = 6, - CLOSE_WAIT = 7, - CLOSING = 8, - LAST_ACK = 9, - TIME_WAIT = 10 -}; - -#if LWIP_CALLBACK_API - /* Function to call when a listener has been connected. - * @param arg user-supplied argument (tcp_pcb.callback_arg) - * @param pcb a new tcp_pcb that now is connected - * @param err an error argument (TODO: that is current always ERR_OK?) - * @return ERR_OK: accept the new connection, - * any other err_t abortsthe new connection - */ -#define DEF_ACCEPT_CALLBACK tcp_accept_fn accept; -#else /* LWIP_CALLBACK_API */ -#define DEF_ACCEPT_CALLBACK -#endif /* LWIP_CALLBACK_API */ - -/** - * members common to struct tcp_pcb and struct tcp_listen_pcb - */ -#define TCP_PCB_COMMON(type) \ - type *next; /* for the linked list */ \ - void *callback_arg; \ - /* the accept callback for listen- and normal pcbs, if LWIP_CALLBACK_API */ \ - DEF_ACCEPT_CALLBACK \ - enum tcp_state state; /* TCP state */ \ - u8_t prio; \ - /* ports are in host byte order */ \ - u16_t local_port - - -/* the TCP protocol control block */ -struct tcp_pcb { -/** common PCB members */ - IP_PCB; -/** protocol specific PCB members */ - TCP_PCB_COMMON(struct tcp_pcb); - - /* ports are in host byte order */ - u16_t remote_port; - - u8_t flags; -#define TF_ACK_DELAY ((u8_t)0x01U) /* Delayed ACK. */ -#define TF_ACK_NOW ((u8_t)0x02U) /* Immediate ACK. */ -#define TF_INFR ((u8_t)0x04U) /* In fast recovery. */ -#define TF_TIMESTAMP ((u8_t)0x08U) /* Timestamp option enabled */ -#define TF_RXCLOSED ((u8_t)0x10U) /* rx closed by tcp_shutdown */ -#define TF_FIN ((u8_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */ -#define TF_NODELAY ((u8_t)0x40U) /* Disable Nagle algorithm */ -#define TF_NAGLEMEMERR ((u8_t)0x80U) /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ - - /* the rest of the fields are in host byte order - as we have to do some math with them */ - - /* Timers */ - u8_t polltmr, pollinterval; - u8_t last_timer; - u32_t tmr; - - /* receiver variables */ - u32_t rcv_nxt; /* next seqno expected */ - u16_t rcv_wnd; /* receiver window available */ - u16_t rcv_ann_wnd; /* receiver window to announce */ - u32_t rcv_ann_right_edge; /* announced right edge of window */ - - /* Retransmission timer. */ - s16_t rtime; - - u16_t mss; /* maximum segment size */ - - /* RTT (round trip time) estimation variables */ - u32_t rttest; /* RTT estimate in 500ms ticks */ - u32_t rtseq; /* sequence number being timed */ - s16_t sa, sv; /* @todo document this */ - - s16_t rto; /* retransmission time-out */ - u8_t nrtx; /* number of retransmissions */ - - /* fast retransmit/recovery */ - u8_t dupacks; - u32_t lastack; /* Highest acknowledged seqno. */ - - /* congestion avoidance/control variables */ - u16_t cwnd; - u16_t ssthresh; - - /* sender variables */ - u32_t snd_nxt; /* next new seqno to be sent */ - u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last - window update. */ - u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ - u16_t snd_wnd; /* sender window */ - u16_t snd_wnd_max; /* the maximum sender window announced by the remote host */ - - u16_t acked; - - u16_t snd_buf; /* Available buffer space for sending (in bytes). */ -#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) - u16_t snd_queuelen; /* Available buffer space for sending (in pbufs). */ - -#if TCP_OVERSIZE - /* Extra bytes available at the end of the last pbuf in unsent. */ - u16_t unsent_oversize; -#endif /* TCP_OVERSIZE */ - - /* These are ordered by sequence number: */ - struct tcp_seg *unsent; /* Unsent (queued) segments. */ - struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ -#if TCP_QUEUE_OOSEQ - struct tcp_seg *ooseq; /* Received out of sequence segments. */ -#endif /* TCP_QUEUE_OOSEQ */ - - struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ - -#if LWIP_CALLBACK_API - /* Function to be called when more send buffer space is available. */ - tcp_sent_fn sent; - /* Function to be called when (in-sequence) data has arrived. */ - tcp_recv_fn recv; - /* Function to be called when a connection has been set up. */ - tcp_connected_fn connected; - /* Function which is called periodically. */ - tcp_poll_fn poll; - /* Function to be called whenever a fatal error occurs. */ - tcp_err_fn errf; -#endif /* LWIP_CALLBACK_API */ - -#if LWIP_TCP_TIMESTAMPS - u32_t ts_lastacksent; - u32_t ts_recent; -#endif /* LWIP_TCP_TIMESTAMPS */ - - /* idle time before KEEPALIVE is sent */ - u32_t keep_idle; -#if LWIP_TCP_KEEPALIVE - u32_t keep_intvl; - u32_t keep_cnt; -#endif /* LWIP_TCP_KEEPALIVE */ - - /* Persist timer counter */ - u8_t persist_cnt; - /* Persist timer back-off */ - u8_t persist_backoff; - - /* KEEPALIVE counter */ - u8_t keep_cnt_sent; -}; - -struct tcp_pcb_listen { -/* Common members of all PCB types */ - IP_PCB; -/* Protocol specific PCB members */ - TCP_PCB_COMMON(struct tcp_pcb_listen); - -#if TCP_LISTEN_BACKLOG - u8_t backlog; - u8_t accepts_pending; -#endif /* TCP_LISTEN_BACKLOG */ -#if LWIP_IPV6 - u8_t accept_any_ip_version; -#endif /* LWIP_IPV6 */ -}; - -#if LWIP_EVENT_API - -enum lwip_event { - LWIP_EVENT_ACCEPT, - LWIP_EVENT_SENT, - LWIP_EVENT_RECV, - LWIP_EVENT_CONNECTED, - LWIP_EVENT_POLL, - LWIP_EVENT_ERR -}; - -err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, - enum lwip_event, - struct pbuf *p, - u16_t size, - err_t err); - -#endif /* LWIP_EVENT_API */ - -/* Application program's interface: */ -struct tcp_pcb * tcp_new (void); - -void tcp_arg (struct tcp_pcb *pcb, void *arg); -void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); -void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); -void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); -void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); -void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); - -#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) -#define tcp_sndbuf(pcb) ((pcb)->snd_buf) -#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) -#define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY) -#define tcp_nagle_enable(pcb) ((pcb)->flags &= ~TF_NODELAY) -#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0) - -#if TCP_LISTEN_BACKLOG -#define tcp_accepted(pcb) do { \ - LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", pcb->state == LISTEN); \ - (((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0) -#else /* TCP_LISTEN_BACKLOG */ -#define tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \ - (pcb)->state == LISTEN) -#endif /* TCP_LISTEN_BACKLOG */ - -void tcp_recved (struct tcp_pcb *pcb, u16_t len); -err_t tcp_bind (struct tcp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port); -err_t tcp_connect (struct tcp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port, tcp_connected_fn connected); - -struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); -#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) - -void tcp_abort (struct tcp_pcb *pcb); -err_t tcp_close (struct tcp_pcb *pcb); -err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); - -/* Flags for "apiflags" parameter in tcp_write */ -#define TCP_WRITE_FLAG_COPY 0x01 -#define TCP_WRITE_FLAG_MORE 0x02 - -err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, - u8_t apiflags); - -void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); - -#define TCP_PRIO_MIN 1 -#define TCP_PRIO_NORMAL 64 -#define TCP_PRIO_MAX 127 - -err_t tcp_output (struct tcp_pcb *pcb); - - -const char* tcp_debug_state_str(enum tcp_state s); - -#if LWIP_IPV6 -struct tcp_pcb * tcp_new_ip6 (void); -#define tcp_bind_ip6(pcb, ip6addr, port) \ - tcp_bind(pcb, ip6_2_ip(ip6addr), port) -#define tcp_connect_ip6(pcb, ip6addr, port, connected) \ - tcp_connect(pcb, ip6_2_ip(ip6addr), port, connected) -struct tcp_pcb * tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog); -#define tcp_listen_dual(pcb) tcp_listen_dual_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) -#else /* LWIP_IPV6 */ -#define tcp_listen_dual_with_backlog(pcb, backlog) tcp_listen_with_backlog(pcb, backlog) -#define tcp_listen_dual(pcb) tcp_listen(pcb) -#endif /* LWIP_IPV6 */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TCP */ - -#endif /* __LWIP_TCP_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_TCP_H__ +#define __LWIP_TCP_H__ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/ip.h" +#include "lwip/icmp.h" +#include "lwip/err.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct tcp_pcb; + +/** Function prototype for tcp accept callback functions. Called when a new + * connection can be accepted on a listening pcb. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param newpcb The new connection pcb + * @param err An error code if there has been an error accepting. + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); + +/** Function prototype for tcp receive callback functions. Called when data has + * been received. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb which received data + * @param p The received data (or NULL when the connection has been closed!) + * @param err An error code if there has been an error receiving + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, + struct pbuf *p, err_t err); + +/** Function prototype for tcp sent callback functions. Called when sent data has + * been acknowledged by the remote side. Use it to free corresponding resources. + * This also means that the pcb has now space available to send new data. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb for which data has been acknowledged + * @param len The amount of bytes acknowledged + * @return ERR_OK: try to send some data by calling tcp_output + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, + u16_t len); + +/** Function prototype for tcp poll callback functions. Called periodically as + * specified by @see tcp_poll. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb tcp pcb + * @return ERR_OK: try to send some data by calling tcp_output + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); + +/** Function prototype for tcp error callback functions. Called when the pcb + * receives a RST or is unexpectedly closed for any other reason. + * + * @note The corresponding pcb is already freed when this callback is called! + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param err Error code to indicate why the pcb has been closed + * ERR_ABRT: aborted through tcp_abort or by a TCP timer + * ERR_RST: the connection was reset by the remote host + */ +typedef void (*tcp_err_fn)(void *arg, err_t err); + +/** Function prototype for tcp connected callback functions. Called when a pcb + * is connected to the remote side after initiating a connection attempt by + * calling tcp_connect(). + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb which is connected + * @param err An unused error code, always ERR_OK currently ;-) TODO! + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + * + * @note When a connection attempt fails, the error callback is currently called! + */ +typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); + +enum tcp_state { + CLOSED = 0, + LISTEN = 1, + SYN_SENT = 2, + SYN_RCVD = 3, + ESTABLISHED = 4, + FIN_WAIT_1 = 5, + FIN_WAIT_2 = 6, + CLOSE_WAIT = 7, + CLOSING = 8, + LAST_ACK = 9, + TIME_WAIT = 10 +}; + +#if LWIP_CALLBACK_API + /* Function to call when a listener has been connected. + * @param arg user-supplied argument (tcp_pcb.callback_arg) + * @param pcb a new tcp_pcb that now is connected + * @param err an error argument (TODO: that is current always ERR_OK?) + * @return ERR_OK: accept the new connection, + * any other err_t abortsthe new connection + */ +#define DEF_ACCEPT_CALLBACK tcp_accept_fn accept; +#else /* LWIP_CALLBACK_API */ +#define DEF_ACCEPT_CALLBACK +#endif /* LWIP_CALLBACK_API */ + +/** + * members common to struct tcp_pcb and struct tcp_listen_pcb + */ +#define TCP_PCB_COMMON(type) \ + type *next; /* for the linked list */ \ + void *callback_arg; \ + /* the accept callback for listen- and normal pcbs, if LWIP_CALLBACK_API */ \ + DEF_ACCEPT_CALLBACK \ + enum tcp_state state; /* TCP state */ \ + u8_t prio; \ + /* ports are in host byte order */ \ + u16_t local_port + + +/* the TCP protocol control block */ +struct tcp_pcb { +/** common PCB members */ + IP_PCB; +/** protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb); + + /* ports are in host byte order */ + u16_t remote_port; + + u8_t flags; +#define TF_ACK_DELAY ((u8_t)0x01U) /* Delayed ACK. */ +#define TF_ACK_NOW ((u8_t)0x02U) /* Immediate ACK. */ +#define TF_INFR ((u8_t)0x04U) /* In fast recovery. */ +#define TF_TIMESTAMP ((u8_t)0x08U) /* Timestamp option enabled */ +#define TF_RXCLOSED ((u8_t)0x10U) /* rx closed by tcp_shutdown */ +#define TF_FIN ((u8_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */ +#define TF_NODELAY ((u8_t)0x40U) /* Disable Nagle algorithm */ +#define TF_NAGLEMEMERR ((u8_t)0x80U) /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ + + /* the rest of the fields are in host byte order + as we have to do some math with them */ + + /* Timers */ + u8_t polltmr, pollinterval; + u8_t last_timer; + u32_t tmr; + + /* receiver variables */ + u32_t rcv_nxt; /* next seqno expected */ + u16_t rcv_wnd; /* receiver window available */ + u16_t rcv_ann_wnd; /* receiver window to announce */ + u32_t rcv_ann_right_edge; /* announced right edge of window */ + + /* Retransmission timer. */ + s16_t rtime; + + u16_t mss; /* maximum segment size */ + + /* RTT (round trip time) estimation variables */ + u32_t rttest; /* RTT estimate in 500ms ticks */ + u32_t rtseq; /* sequence number being timed */ + s16_t sa, sv; /* @todo document this */ + + s16_t rto; /* retransmission time-out */ + u8_t nrtx; /* number of retransmissions */ + + /* fast retransmit/recovery */ + u8_t dupacks; + u32_t lastack; /* Highest acknowledged seqno. */ + + /* congestion avoidance/control variables */ + u16_t cwnd; + u16_t ssthresh; + + /* sender variables */ + u32_t snd_nxt; /* next new seqno to be sent */ + u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last + window update. */ + u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ + u16_t snd_wnd; /* sender window */ + u16_t snd_wnd_max; /* the maximum sender window announced by the remote host */ + + u16_t acked; + + u16_t snd_buf; /* Available buffer space for sending (in bytes). */ +#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) + u16_t snd_queuelen; /* Available buffer space for sending (in pbufs). */ + +#if TCP_OVERSIZE + /* Extra bytes available at the end of the last pbuf in unsent. */ + u16_t unsent_oversize; +#endif /* TCP_OVERSIZE */ + + /* These are ordered by sequence number: */ + struct tcp_seg *unsent; /* Unsent (queued) segments. */ + struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ +#if TCP_QUEUE_OOSEQ + struct tcp_seg *ooseq; /* Received out of sequence segments. */ +#endif /* TCP_QUEUE_OOSEQ */ + + struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ + +#if LWIP_CALLBACK_API + /* Function to be called when more send buffer space is available. */ + tcp_sent_fn sent; + /* Function to be called when (in-sequence) data has arrived. */ + tcp_recv_fn recv; + /* Function to be called when a connection has been set up. */ + tcp_connected_fn connected; + /* Function which is called periodically. */ + tcp_poll_fn poll; + /* Function to be called whenever a fatal error occurs. */ + tcp_err_fn errf; +#endif /* LWIP_CALLBACK_API */ + +#if LWIP_TCP_TIMESTAMPS + u32_t ts_lastacksent; + u32_t ts_recent; +#endif /* LWIP_TCP_TIMESTAMPS */ + + /* idle time before KEEPALIVE is sent */ + u32_t keep_idle; +#if LWIP_TCP_KEEPALIVE + u32_t keep_intvl; + u32_t keep_cnt; +#endif /* LWIP_TCP_KEEPALIVE */ + + /* Persist timer counter */ + u8_t persist_cnt; + /* Persist timer back-off */ + u8_t persist_backoff; + + /* KEEPALIVE counter */ + u8_t keep_cnt_sent; +}; + +struct tcp_pcb_listen { +/* Common members of all PCB types */ + IP_PCB; +/* Protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb_listen); + +#if TCP_LISTEN_BACKLOG + u8_t backlog; + u8_t accepts_pending; +#endif /* TCP_LISTEN_BACKLOG */ +#if LWIP_IPV6 + u8_t accept_any_ip_version; +#endif /* LWIP_IPV6 */ +}; + +#if LWIP_EVENT_API + +enum lwip_event { + LWIP_EVENT_ACCEPT, + LWIP_EVENT_SENT, + LWIP_EVENT_RECV, + LWIP_EVENT_CONNECTED, + LWIP_EVENT_POLL, + LWIP_EVENT_ERR +}; + +err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, + enum lwip_event, + struct pbuf *p, + u16_t size, + err_t err); + +#endif /* LWIP_EVENT_API */ + +/* Application program's interface: */ +struct tcp_pcb * tcp_new (void); + +void tcp_arg (struct tcp_pcb *pcb, void *arg); +void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); +void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); +void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); +void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); +void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); + +#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) +#define tcp_sndbuf(pcb) ((pcb)->snd_buf) +#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) +#define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY) +#define tcp_nagle_enable(pcb) ((pcb)->flags &= ~TF_NODELAY) +#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0) + +#if TCP_LISTEN_BACKLOG +#define tcp_accepted(pcb) do { \ + LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", pcb->state == LISTEN); \ + (((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0) +#else /* TCP_LISTEN_BACKLOG */ +#define tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \ + (pcb)->state == LISTEN) +#endif /* TCP_LISTEN_BACKLOG */ + +void tcp_recved (struct tcp_pcb *pcb, u16_t len); +err_t tcp_bind (struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +err_t tcp_connect (struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port, tcp_connected_fn connected); + +struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); +#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) + +void tcp_abort (struct tcp_pcb *pcb); +err_t tcp_close (struct tcp_pcb *pcb); +err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); + +/* Flags for "apiflags" parameter in tcp_write */ +#define TCP_WRITE_FLAG_COPY 0x01 +#define TCP_WRITE_FLAG_MORE 0x02 + +err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, + u8_t apiflags); + +void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); + +#define TCP_PRIO_MIN 1 +#define TCP_PRIO_NORMAL 64 +#define TCP_PRIO_MAX 127 + +err_t tcp_output (struct tcp_pcb *pcb); + + +const char* tcp_debug_state_str(enum tcp_state s); + +#if LWIP_IPV6 +struct tcp_pcb * tcp_new_ip6 (void); +#define tcp_bind_ip6(pcb, ip6addr, port) \ + tcp_bind(pcb, ip6_2_ip(ip6addr), port) +#define tcp_connect_ip6(pcb, ip6addr, port, connected) \ + tcp_connect(pcb, ip6_2_ip(ip6addr), port, connected) +struct tcp_pcb * tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog); +#define tcp_listen_dual(pcb) tcp_listen_dual_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) +#else /* LWIP_IPV6 */ +#define tcp_listen_dual_with_backlog(pcb, backlog) tcp_listen_with_backlog(pcb, backlog) +#define tcp_listen_dual(pcb) tcp_listen(pcb) +#endif /* LWIP_IPV6 */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TCP */ + +#endif /* __LWIP_TCP_H__ */ diff --git a/include/lwip/lwip/tcp_impl.h b/include/lwip/lwip/tcp_impl.h index eb14efc8..2afc20d3 100644 --- a/include/lwip/lwip/tcp_impl.h +++ b/include/lwip/lwip/tcp_impl.h @@ -1,508 +1,508 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_TCP_IMPL_H__ -#define __LWIP_TCP_IMPL_H__ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcp.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/icmp.h" -#include "lwip/err.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Functions for interfacing with TCP: */ - -/* Lower layer interface to TCP: */ -void tcp_init (void); /* Initialize this module. */ -void tcp_tmr (void); /* Must be called every - TCP_TMR_INTERVAL - ms. (Typically 250 ms). */ -/* It is also possible to call these two functions at the right - intervals (instead of calling tcp_tmr()). */ -void tcp_slowtmr (void); -void tcp_fasttmr (void); - - -/* Only used by IP to pass a TCP segment to TCP: */ -void tcp_input (struct pbuf *p, struct netif *inp); -/* Used within the TCP code only: */ -struct tcp_pcb * tcp_alloc (u8_t prio); -void tcp_abandon (struct tcp_pcb *pcb, int reset); -err_t tcp_send_empty_ack(struct tcp_pcb *pcb); -void tcp_rexmit (struct tcp_pcb *pcb); -void tcp_rexmit_rto (struct tcp_pcb *pcb); -void tcp_rexmit_fast (struct tcp_pcb *pcb); -u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); -err_t tcp_process_refused_data(struct tcp_pcb *pcb); - -/** - * This is the Nagle algorithm: try to combine user data to send as few TCP - * segments as possible. Only send if - * - no previously transmitted data on the connection remains unacknowledged or - * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or - * - the only unsent segment is at least pcb->mss bytes long (or there is more - * than one unsent segment - with lwIP, this can happen although unsent->len < mss) - * - or if we are in fast-retransmit (TF_INFR) - */ -#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ - ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ - (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ - ((tpcb)->unsent->len >= (tpcb)->mss))) || \ - ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ - ) ? 1 : 0) -#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) - - -#define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) -#define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) -#define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) -#define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) -/* is b<=a<=c? */ -#if 0 /* see bug #10548 */ -#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) -#endif -#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) -#define TCP_FIN 0x01U -#define TCP_SYN 0x02U -#define TCP_RST 0x04U -#define TCP_PSH 0x08U -#define TCP_ACK 0x10U -#define TCP_URG 0x20U -#define TCP_ECE 0x40U -#define TCP_CWR 0x80U - -#define TCP_FLAGS 0x3fU - -/* Length of the TCP header, excluding options. */ -#define TCP_HLEN 20 - -#ifndef TCP_TMR_INTERVAL -#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */ -#endif /* TCP_TMR_INTERVAL */ - -#ifndef TCP_FAST_INTERVAL -#define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */ -#endif /* TCP_FAST_INTERVAL */ - -#ifndef TCP_SLOW_INTERVAL -#define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */ -#endif /* TCP_SLOW_INTERVAL */ - -#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */ -#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */ - -#define TCP_OOSEQ_TIMEOUT 6U /* x RTO */ - -#ifndef TCP_MSL -#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */ -#endif - -/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */ -#ifndef TCP_KEEPIDLE_DEFAULT -#define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */ -#endif - -#ifndef TCP_KEEPINTVL_DEFAULT -#define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */ -#endif - -#ifndef TCP_KEEPCNT_DEFAULT -#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */ -#endif - -#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */ - -/* Fields are (of course) in network byte order. - * Some fields are converted to host byte order in tcp_input(). - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct tcp_hdr { - PACK_STRUCT_FIELD(u16_t src); - PACK_STRUCT_FIELD(u16_t dest); - PACK_STRUCT_FIELD(u32_t seqno); - PACK_STRUCT_FIELD(u32_t ackno); - PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); - PACK_STRUCT_FIELD(u16_t wnd); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t urgp); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12) -#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS) - -#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr)) -#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags)) -#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags)) - -#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags)) -#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) ) - -#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0)) - -/** Flags used on input processing, not on pcb->flags -*/ -#define TF_RESET (u8_t)0x08U /* Connection was reset. */ -#define TF_CLOSED (u8_t)0x10U /* Connection was sucessfully closed. */ -#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */ - - -#if LWIP_EVENT_API - -#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_ACCEPT, NULL, 0, err) -#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_SENT, NULL, space, ERR_OK) -#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_RECV, (p), 0, (err)) -#define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_RECV, NULL, 0, ERR_OK) -#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_CONNECTED, NULL, 0, (err)) -#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_POLL, NULL, 0, ERR_OK) -#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \ - LWIP_EVENT_ERR, NULL, 0, (err)) - -#else /* LWIP_EVENT_API */ - -#define TCP_EVENT_ACCEPT(pcb,err,ret) \ - do { \ - if((pcb)->accept != NULL) \ - (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \ - else (ret) = ERR_ARG; \ - } while (0) - -#define TCP_EVENT_SENT(pcb,space,ret) \ - do { \ - if((pcb)->sent != NULL) \ - (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_RECV(pcb,p,err,ret) \ - do { \ - if((pcb)->recv != NULL) { \ - (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\ - } else { \ - (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \ - } \ - } while (0) - -#define TCP_EVENT_CLOSED(pcb,ret) \ - do { \ - if(((pcb)->recv != NULL)) { \ - (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\ - } else { \ - (ret) = ERR_OK; \ - } \ - } while (0) - -#define TCP_EVENT_CONNECTED(pcb,err,ret) \ - do { \ - if((pcb)->connected != NULL) \ - (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_POLL(pcb,ret) \ - do { \ - if((pcb)->poll != NULL) \ - (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_ERR(errf,arg,err) \ - do { \ - if((errf) != NULL) \ - (errf)((arg),(err)); \ - } while (0) - -#endif /* LWIP_EVENT_API */ - -/** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */ -#if TCP_OVERSIZE && defined(LWIP_DEBUG) -#define TCP_OVERSIZE_DBGCHECK 1 -#else -#define TCP_OVERSIZE_DBGCHECK 0 -#endif - -/** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */ -#define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP) - -/* This structure represents a TCP segment on the unsent, unacked and ooseq queues */ -struct tcp_seg { - struct tcp_seg *next; /* used when putting segements on a queue */ - struct pbuf *p; /* buffer containing data + TCP header */ - u16_t len; /* the TCP length of this segment */ -#if TCP_OVERSIZE_DBGCHECK - u16_t oversize_left; /* Extra bytes available at the end of the last - pbuf in unsent (used for asserting vs. - tcp_pcb.unsent_oversized only) */ -#endif /* TCP_OVERSIZE_DBGCHECK */ -#if TCP_CHECKSUM_ON_COPY - u16_t chksum; - u8_t chksum_swapped; -#endif /* TCP_CHECKSUM_ON_COPY */ - u8_t flags; -#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */ -#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ -#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is - checksummed into 'chksum' */ - struct tcp_hdr *tcphdr; /* the TCP header */ -}; - -#define LWIP_TCP_OPT_LENGTH(flags) \ - (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \ - (flags & TF_SEG_OPTS_TS ? 12 : 0) - -/** This returns a TCP header option for MSS in an u32_t */ -#define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF)) - -/* Global variables: */ -extern struct tcp_pcb *tcp_input_pcb; -extern u32_t tcp_ticks; -extern u8_t tcp_active_pcbs_changed; - -/* The TCP PCB lists. */ -union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ - struct tcp_pcb_listen *listen_pcbs; - struct tcp_pcb *pcbs; -}; -extern struct tcp_pcb *tcp_bound_pcbs; -extern union tcp_listen_pcbs_t tcp_listen_pcbs; -extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a - state in which they accept or send - data. */ -extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ - -extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ - -/* Axioms about the above lists: - 1) Every TCP PCB that is not CLOSED is in one of the lists. - 2) A PCB is only in one of the lists. - 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state. - 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state. -*/ -/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB - with a PCB list or removes a PCB from a list, respectively. */ -#ifndef TCP_DEBUG_PCB_LISTS -#define TCP_DEBUG_PCB_LISTS 0 -#endif -#if TCP_DEBUG_PCB_LISTS -#define TCP_REG(pcbs, npcb) do {\ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \ - for(tcp_tmp_pcb = *(pcbs); \ - tcp_tmp_pcb != NULL; \ - tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ - } \ - LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ - (npcb)->next = *(pcbs); \ - LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \ - *(pcbs) = (npcb); \ - LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ - tcp_timer_needed(); \ - } while(0) -#define TCP_RMV(pcbs, npcb) do { \ - LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \ - if(*(pcbs) == (npcb)) { \ - *(pcbs) = (*pcbs)->next; \ - } else for(tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - if(tcp_tmp_pcb->next == (npcb)) { \ - tcp_tmp_pcb->next = (npcb)->next; \ - break; \ - } \ - } \ - (npcb)->next = NULL; \ - LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \ - } while(0) - -#else /* LWIP_DEBUG */ - -#define TCP_REG(pcbs, npcb) \ - do { \ - (npcb)->next = *pcbs; \ - *(pcbs) = (npcb); \ - tcp_timer_needed(); \ - } while (0) - -#define TCP_RMV(pcbs, npcb) \ - do { \ - if(*(pcbs) == (npcb)) { \ - (*(pcbs)) = (*pcbs)->next; \ - } \ - else { \ - for(tcp_tmp_pcb = *pcbs; \ - tcp_tmp_pcb != NULL; \ - tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - if(tcp_tmp_pcb->next == (npcb)) { \ - tcp_tmp_pcb->next = (npcb)->next; \ - break; \ - } \ - } \ - } \ - (npcb)->next = NULL; \ - } while(0) - -#endif /* LWIP_DEBUG */ - -#define TCP_REG_ACTIVE(npcb) \ - do { \ - TCP_REG(&tcp_active_pcbs, npcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - -#define TCP_RMV_ACTIVE(npcb) \ - do { \ - TCP_RMV(&tcp_active_pcbs, npcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - -#define TCP_PCB_REMOVE_ACTIVE(pcb) \ - do { \ - tcp_pcb_remove(&tcp_active_pcbs, pcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - - -/* Internal functions: */ -struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); -void tcp_pcb_purge(struct tcp_pcb *pcb); -void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); - -void tcp_segs_free(struct tcp_seg *seg); -void tcp_seg_free(struct tcp_seg *seg); -struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); - -#define tcp_ack(pcb) \ - do { \ - if((pcb)->flags & TF_ACK_DELAY) { \ - (pcb)->flags &= ~TF_ACK_DELAY; \ - (pcb)->flags |= TF_ACK_NOW; \ - } \ - else { \ - (pcb)->flags |= TF_ACK_DELAY; \ - } \ - } while (0) - -#define tcp_ack_now(pcb) \ - do { \ - (pcb)->flags |= TF_ACK_NOW; \ - } while (0) - -err_t tcp_send_fin(struct tcp_pcb *pcb); -err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags); - -void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); - -void tcp_rst_impl(u32_t seqno, u32_t ackno, - ipX_addr_t *local_ip, ipX_addr_t *remote_ip, - u16_t local_port, u16_t remote_port -#if LWIP_IPV6 - , u8_t isipv6 -#endif /* LWIP_IPV6 */ - ); -#if LWIP_IPV6 -#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ - tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) -#else /* LWIP_IPV6 */ -#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ - tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port) -#endif /* LWIP_IPV6 */ - -u32_t tcp_next_iss(void); - -void tcp_keepalive(struct tcp_pcb *pcb); -void tcp_zero_window_probe(struct tcp_pcb *pcb); - -#if TCP_CALCULATE_EFF_SEND_MSS -u16_t tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest -#if LWIP_IPV6 - , ipX_addr_t *src, u8_t isipv6 -#endif /* LWIP_IPV6 */ - ); -#if LWIP_IPV6 -#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest, src, isipv6) -#else /* LWIP_IPV6 */ -#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest) -#endif /* LWIP_IPV6 */ -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - -#if LWIP_CALLBACK_API -err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); -#endif /* LWIP_CALLBACK_API */ - -#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG -void tcp_debug_print(struct tcp_hdr *tcphdr); -void tcp_debug_print_flags(u8_t flags); -void tcp_debug_print_state(enum tcp_state s); -void tcp_debug_print_pcbs(void); -s16_t tcp_pcbs_sane(void); -#else -# define tcp_debug_print(tcphdr) -# define tcp_debug_print_flags(flags) -# define tcp_debug_print_state(s) -# define tcp_debug_print_pcbs() -# define tcp_pcbs_sane() 1 -#endif /* TCP_DEBUG */ - -/** External function (implemented in timers.c), called when TCP detects - * that a timer is needed (i.e. active- or time-wait-pcb found). */ -void tcp_timer_needed(void); - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TCP */ - -#endif /* __LWIP_TCP_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_TCP_IMPL_H__ +#define __LWIP_TCP_IMPL_H__ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/ip.h" +#include "lwip/icmp.h" +#include "lwip/err.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Functions for interfacing with TCP: */ + +/* Lower layer interface to TCP: */ +void tcp_init (void); /* Initialize this module. */ +void tcp_tmr (void); /* Must be called every + TCP_TMR_INTERVAL + ms. (Typically 250 ms). */ +/* It is also possible to call these two functions at the right + intervals (instead of calling tcp_tmr()). */ +void tcp_slowtmr (void); +void tcp_fasttmr (void); + + +/* Only used by IP to pass a TCP segment to TCP: */ +void tcp_input (struct pbuf *p, struct netif *inp); +/* Used within the TCP code only: */ +struct tcp_pcb * tcp_alloc (u8_t prio); +void tcp_abandon (struct tcp_pcb *pcb, int reset); +err_t tcp_send_empty_ack(struct tcp_pcb *pcb); +void tcp_rexmit (struct tcp_pcb *pcb); +void tcp_rexmit_rto (struct tcp_pcb *pcb); +void tcp_rexmit_fast (struct tcp_pcb *pcb); +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); +err_t tcp_process_refused_data(struct tcp_pcb *pcb); + +/** + * This is the Nagle algorithm: try to combine user data to send as few TCP + * segments as possible. Only send if + * - no previously transmitted data on the connection remains unacknowledged or + * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or + * - the only unsent segment is at least pcb->mss bytes long (or there is more + * than one unsent segment - with lwIP, this can happen although unsent->len < mss) + * - or if we are in fast-retransmit (TF_INFR) + */ +#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ + ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ + (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ + ((tpcb)->unsent->len >= (tpcb)->mss))) || \ + ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ + ) ? 1 : 0) +#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) + + +#define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) +#define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) +#define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) +#define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) +/* is b<=a<=c? */ +#if 0 /* see bug #10548 */ +#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) +#endif +#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) +#define TCP_FIN 0x01U +#define TCP_SYN 0x02U +#define TCP_RST 0x04U +#define TCP_PSH 0x08U +#define TCP_ACK 0x10U +#define TCP_URG 0x20U +#define TCP_ECE 0x40U +#define TCP_CWR 0x80U + +#define TCP_FLAGS 0x3fU + +/* Length of the TCP header, excluding options. */ +#define TCP_HLEN 20 + +#ifndef TCP_TMR_INTERVAL +#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */ +#endif /* TCP_TMR_INTERVAL */ + +#ifndef TCP_FAST_INTERVAL +#define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */ +#endif /* TCP_FAST_INTERVAL */ + +#ifndef TCP_SLOW_INTERVAL +#define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */ +#endif /* TCP_SLOW_INTERVAL */ + +#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */ +#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */ + +#define TCP_OOSEQ_TIMEOUT 6U /* x RTO */ + +#ifndef TCP_MSL +#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */ +#endif + +/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */ +#ifndef TCP_KEEPIDLE_DEFAULT +#define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */ +#endif + +#ifndef TCP_KEEPINTVL_DEFAULT +#define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */ +#endif + +#ifndef TCP_KEEPCNT_DEFAULT +#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */ +#endif + +#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */ + +/* Fields are (of course) in network byte order. + * Some fields are converted to host byte order in tcp_input(). + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct tcp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); + PACK_STRUCT_FIELD(u32_t seqno); + PACK_STRUCT_FIELD(u32_t ackno); + PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); + PACK_STRUCT_FIELD(u16_t wnd); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t urgp); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12) +#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS) + +#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr)) +#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags)) +#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags)) + +#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags)) +#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) ) + +#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0)) + +/** Flags used on input processing, not on pcb->flags +*/ +#define TF_RESET (u8_t)0x08U /* Connection was reset. */ +#define TF_CLOSED (u8_t)0x10U /* Connection was sucessfully closed. */ +#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */ + + +#if LWIP_EVENT_API + +#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_ACCEPT, NULL, 0, err) +#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_SENT, NULL, space, ERR_OK) +#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_RECV, (p), 0, (err)) +#define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_RECV, NULL, 0, ERR_OK) +#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_CONNECTED, NULL, 0, (err)) +#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_POLL, NULL, 0, ERR_OK) +#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \ + LWIP_EVENT_ERR, NULL, 0, (err)) + +#else /* LWIP_EVENT_API */ + +#define TCP_EVENT_ACCEPT(pcb,err,ret) \ + do { \ + if((pcb)->accept != NULL) \ + (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \ + else (ret) = ERR_ARG; \ + } while (0) + +#define TCP_EVENT_SENT(pcb,space,ret) \ + do { \ + if((pcb)->sent != NULL) \ + (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_RECV(pcb,p,err,ret) \ + do { \ + if((pcb)->recv != NULL) { \ + (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\ + } else { \ + (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \ + } \ + } while (0) + +#define TCP_EVENT_CLOSED(pcb,ret) \ + do { \ + if(((pcb)->recv != NULL)) { \ + (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\ + } else { \ + (ret) = ERR_OK; \ + } \ + } while (0) + +#define TCP_EVENT_CONNECTED(pcb,err,ret) \ + do { \ + if((pcb)->connected != NULL) \ + (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_POLL(pcb,ret) \ + do { \ + if((pcb)->poll != NULL) \ + (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_ERR(errf,arg,err) \ + do { \ + if((errf) != NULL) \ + (errf)((arg),(err)); \ + } while (0) + +#endif /* LWIP_EVENT_API */ + +/** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */ +#if TCP_OVERSIZE && defined(LWIP_DEBUG) +#define TCP_OVERSIZE_DBGCHECK 1 +#else +#define TCP_OVERSIZE_DBGCHECK 0 +#endif + +/** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */ +#define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP) + +/* This structure represents a TCP segment on the unsent, unacked and ooseq queues */ +struct tcp_seg { + struct tcp_seg *next; /* used when putting segements on a queue */ + struct pbuf *p; /* buffer containing data + TCP header */ + u16_t len; /* the TCP length of this segment */ +#if TCP_OVERSIZE_DBGCHECK + u16_t oversize_left; /* Extra bytes available at the end of the last + pbuf in unsent (used for asserting vs. + tcp_pcb.unsent_oversized only) */ +#endif /* TCP_OVERSIZE_DBGCHECK */ +#if TCP_CHECKSUM_ON_COPY + u16_t chksum; + u8_t chksum_swapped; +#endif /* TCP_CHECKSUM_ON_COPY */ + u8_t flags; +#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */ +#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ +#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is + checksummed into 'chksum' */ + struct tcp_hdr *tcphdr; /* the TCP header */ +}; + +#define LWIP_TCP_OPT_LENGTH(flags) \ + (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \ + (flags & TF_SEG_OPTS_TS ? 12 : 0) + +/** This returns a TCP header option for MSS in an u32_t */ +#define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF)) + +/* Global variables: */ +extern struct tcp_pcb *tcp_input_pcb; +extern u32_t tcp_ticks; +extern u8_t tcp_active_pcbs_changed; + +/* The TCP PCB lists. */ +union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ + struct tcp_pcb_listen *listen_pcbs; + struct tcp_pcb *pcbs; +}; +extern struct tcp_pcb *tcp_bound_pcbs; +extern union tcp_listen_pcbs_t tcp_listen_pcbs; +extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a + state in which they accept or send + data. */ +extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ + +extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ + +/* Axioms about the above lists: + 1) Every TCP PCB that is not CLOSED is in one of the lists. + 2) A PCB is only in one of the lists. + 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state. + 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state. +*/ +/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB + with a PCB list or removes a PCB from a list, respectively. */ +#ifndef TCP_DEBUG_PCB_LISTS +#define TCP_DEBUG_PCB_LISTS 0 +#endif +#if TCP_DEBUG_PCB_LISTS +#define TCP_REG(pcbs, npcb) do {\ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \ + for(tcp_tmp_pcb = *(pcbs); \ + tcp_tmp_pcb != NULL; \ + tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ + } \ + LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ + (npcb)->next = *(pcbs); \ + LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \ + *(pcbs) = (npcb); \ + LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ + tcp_timer_needed(); \ + } while(0) +#define TCP_RMV(pcbs, npcb) do { \ + LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \ + if(*(pcbs) == (npcb)) { \ + *(pcbs) = (*pcbs)->next; \ + } else for(tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + if(tcp_tmp_pcb->next == (npcb)) { \ + tcp_tmp_pcb->next = (npcb)->next; \ + break; \ + } \ + } \ + (npcb)->next = NULL; \ + LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \ + } while(0) + +#else /* LWIP_DEBUG */ + +#define TCP_REG(pcbs, npcb) \ + do { \ + (npcb)->next = *pcbs; \ + *(pcbs) = (npcb); \ + tcp_timer_needed(); \ + } while (0) + +#define TCP_RMV(pcbs, npcb) \ + do { \ + if(*(pcbs) == (npcb)) { \ + (*(pcbs)) = (*pcbs)->next; \ + } \ + else { \ + for(tcp_tmp_pcb = *pcbs; \ + tcp_tmp_pcb != NULL; \ + tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + if(tcp_tmp_pcb->next == (npcb)) { \ + tcp_tmp_pcb->next = (npcb)->next; \ + break; \ + } \ + } \ + } \ + (npcb)->next = NULL; \ + } while(0) + +#endif /* LWIP_DEBUG */ + +#define TCP_REG_ACTIVE(npcb) \ + do { \ + TCP_REG(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + +#define TCP_RMV_ACTIVE(npcb) \ + do { \ + TCP_RMV(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + +#define TCP_PCB_REMOVE_ACTIVE(pcb) \ + do { \ + tcp_pcb_remove(&tcp_active_pcbs, pcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + + +/* Internal functions: */ +struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); +void tcp_pcb_purge(struct tcp_pcb *pcb); +void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); + +void tcp_segs_free(struct tcp_seg *seg); +void tcp_seg_free(struct tcp_seg *seg); +struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); + +#define tcp_ack(pcb) \ + do { \ + if((pcb)->flags & TF_ACK_DELAY) { \ + (pcb)->flags &= ~TF_ACK_DELAY; \ + (pcb)->flags |= TF_ACK_NOW; \ + } \ + else { \ + (pcb)->flags |= TF_ACK_DELAY; \ + } \ + } while (0) + +#define tcp_ack_now(pcb) \ + do { \ + (pcb)->flags |= TF_ACK_NOW; \ + } while (0) + +err_t tcp_send_fin(struct tcp_pcb *pcb); +err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags); + +void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); + +void tcp_rst_impl(u32_t seqno, u32_t ackno, + ipX_addr_t *local_ip, ipX_addr_t *remote_ip, + u16_t local_port, u16_t remote_port +#if LWIP_IPV6 + , u8_t isipv6 +#endif /* LWIP_IPV6 */ + ); +#if LWIP_IPV6 +#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ + tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) +#else /* LWIP_IPV6 */ +#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ + tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port) +#endif /* LWIP_IPV6 */ + +u32_t tcp_next_iss(void); + +void tcp_keepalive(struct tcp_pcb *pcb); +void tcp_zero_window_probe(struct tcp_pcb *pcb); + +#if TCP_CALCULATE_EFF_SEND_MSS +u16_t tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest +#if LWIP_IPV6 + , ipX_addr_t *src, u8_t isipv6 +#endif /* LWIP_IPV6 */ + ); +#if LWIP_IPV6 +#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest, src, isipv6) +#else /* LWIP_IPV6 */ +#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest) +#endif /* LWIP_IPV6 */ +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + +#if LWIP_CALLBACK_API +err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); +#endif /* LWIP_CALLBACK_API */ + +#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG +void tcp_debug_print(struct tcp_hdr *tcphdr); +void tcp_debug_print_flags(u8_t flags); +void tcp_debug_print_state(enum tcp_state s); +void tcp_debug_print_pcbs(void); +s16_t tcp_pcbs_sane(void); +#else +# define tcp_debug_print(tcphdr) +# define tcp_debug_print_flags(flags) +# define tcp_debug_print_state(s) +# define tcp_debug_print_pcbs() +# define tcp_pcbs_sane() 1 +#endif /* TCP_DEBUG */ + +/** External function (implemented in timers.c), called when TCP detects + * that a timer is needed (i.e. active- or time-wait-pcb found). */ +void tcp_timer_needed(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TCP */ + +#endif /* __LWIP_TCP_H__ */ diff --git a/include/lwip/lwip/tcpip.h b/include/lwip/lwip/tcpip.h index 55632c61..74b3a0a3 100644 --- a/include/lwip/lwip/tcpip.h +++ b/include/lwip/lwip/tcpip.h @@ -1,181 +1,181 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_TCPIP_H__ -#define __LWIP_TCPIP_H__ - -#include "lwip/opt.h" - -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/api_msg.h" -#include "lwip/netifapi.h" -#include "lwip/pbuf.h" -#include "lwip/api.h" -#include "lwip/sys.h" -#include "lwip/timers.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Define this to something that triggers a watchdog. This is called from - * tcpip_thread after processing a message. */ -#ifndef LWIP_TCPIP_THREAD_ALIVE -#define LWIP_TCPIP_THREAD_ALIVE() -#endif - -#if LWIP_TCPIP_CORE_LOCKING -/** The global semaphore to lock the stack. */ -extern sys_mutex_t lock_tcpip_core; -#define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core) -#define UNLOCK_TCPIP_CORE() sys_mutex_unlock(&lock_tcpip_core) -#ifdef LWIP_DEBUG -#define TCIP_APIMSG_SET_ERR(m, e) (m)->msg.err = e /* catch functions that don't set err */ -#else -#define TCIP_APIMSG_SET_ERR(m, e) -#endif -#define TCPIP_APIMSG_NOERR(m,f) do { \ - TCIP_APIMSG_SET_ERR(m, ERR_VAL); \ - LOCK_TCPIP_CORE(); \ - f(&((m)->msg)); \ - UNLOCK_TCPIP_CORE(); \ -} while(0) -#define TCPIP_APIMSG(m,f,e) do { \ - TCPIP_APIMSG_NOERR(m,f); \ - (e) = (m)->msg.err; \ -} while(0) -#define TCPIP_APIMSG_ACK(m) -#define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m) -#define TCPIP_NETIFAPI_ACK(m) -#else /* LWIP_TCPIP_CORE_LOCKING */ -#define LOCK_TCPIP_CORE() -#define UNLOCK_TCPIP_CORE() -#define TCPIP_APIMSG_NOERR(m,f) do { (m)->function = f; tcpip_apimsg(m); } while(0) -#define TCPIP_APIMSG(m,f,e) do { (m)->function = f; (e) = tcpip_apimsg(m); } while(0) -#define TCPIP_APIMSG_ACK(m) sys_sem_signal(&m->conn->op_completed) -#define TCPIP_APIMSG_ACK_SND(m) sys_sem_signal(&m->conn->snd_op_completed) - -#define TCPIP_NETIFAPI(m) tcpip_netifapi(m) -#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem) -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -/** Function prototype for the init_done function passed to tcpip_init */ -typedef void (*tcpip_init_done_fn)(void *arg); -/** Function prototype for functions passed to tcpip_callback() */ -typedef void (*tcpip_callback_fn)(void *ctx); - -/* Forward declarations */ -struct tcpip_callback_msg; - -void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); - -#if LWIP_NETCONN -err_t tcpip_apimsg(struct api_msg *apimsg); -#endif /* LWIP_NETCONN */ - -err_t tcpip_input(struct pbuf *p, struct netif *inp); - -#if LWIP_NETIF_API -err_t tcpip_netifapi(struct netifapi_msg *netifapimsg); -#if LWIP_TCPIP_CORE_LOCKING -err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); -#endif /* LWIP_TCPIP_CORE_LOCKING */ -#endif /* LWIP_NETIF_API */ - -err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); -#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) - -struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); -void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg); -err_t tcpip_trycallback(struct tcpip_callback_msg* msg); - -/* free pbufs or heap memory from another context without blocking */ -err_t pbuf_free_callback(struct pbuf *p); -err_t mem_free_callback(void *m); - -#if LWIP_TCPIP_TIMEOUT -err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg); -err_t tcpip_untimeout(sys_timeout_handler h, void *arg); -#endif /* LWIP_TCPIP_TIMEOUT */ - -enum tcpip_msg_type { -#if LWIP_NETCONN - TCPIP_MSG_API, -#endif /* LWIP_NETCONN */ - TCPIP_MSG_INPKT, -#if LWIP_NETIF_API - TCPIP_MSG_NETIFAPI, -#endif /* LWIP_NETIF_API */ -#if LWIP_TCPIP_TIMEOUT - TCPIP_MSG_TIMEOUT, - TCPIP_MSG_UNTIMEOUT, -#endif /* LWIP_TCPIP_TIMEOUT */ - TCPIP_MSG_CALLBACK, - TCPIP_MSG_CALLBACK_STATIC -}; - -struct tcpip_msg { - enum tcpip_msg_type type; - sys_sem_t *sem; - union { -#if LWIP_NETCONN - struct api_msg *apimsg; -#endif /* LWIP_NETCONN */ -#if LWIP_NETIF_API - struct netifapi_msg *netifapimsg; -#endif /* LWIP_NETIF_API */ - struct { - struct pbuf *p; - struct netif *netif; - } inp; - struct { - tcpip_callback_fn function; - void *ctx; - } cb; -#if LWIP_TCPIP_TIMEOUT - struct { - u32_t msecs; - sys_timeout_handler h; - void *arg; - } tmo; -#endif /* LWIP_TCPIP_TIMEOUT */ - } msg; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* !NO_SYS */ - -#endif /* __LWIP_TCPIP_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_TCPIP_H__ +#define __LWIP_TCPIP_H__ + +#include "lwip/opt.h" + +#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api_msg.h" +#include "lwip/netifapi.h" +#include "lwip/pbuf.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/timers.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Define this to something that triggers a watchdog. This is called from + * tcpip_thread after processing a message. */ +#ifndef LWIP_TCPIP_THREAD_ALIVE +#define LWIP_TCPIP_THREAD_ALIVE() +#endif + +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +extern sys_mutex_t lock_tcpip_core; +#define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core) +#define UNLOCK_TCPIP_CORE() sys_mutex_unlock(&lock_tcpip_core) +#ifdef LWIP_DEBUG +#define TCIP_APIMSG_SET_ERR(m, e) (m)->msg.err = e /* catch functions that don't set err */ +#else +#define TCIP_APIMSG_SET_ERR(m, e) +#endif +#define TCPIP_APIMSG_NOERR(m,f) do { \ + TCIP_APIMSG_SET_ERR(m, ERR_VAL); \ + LOCK_TCPIP_CORE(); \ + f(&((m)->msg)); \ + UNLOCK_TCPIP_CORE(); \ +} while(0) +#define TCPIP_APIMSG(m,f,e) do { \ + TCPIP_APIMSG_NOERR(m,f); \ + (e) = (m)->msg.err; \ +} while(0) +#define TCPIP_APIMSG_ACK(m) +#define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m) +#define TCPIP_NETIFAPI_ACK(m) +#else /* LWIP_TCPIP_CORE_LOCKING */ +#define LOCK_TCPIP_CORE() +#define UNLOCK_TCPIP_CORE() +#define TCPIP_APIMSG_NOERR(m,f) do { (m)->function = f; tcpip_apimsg(m); } while(0) +#define TCPIP_APIMSG(m,f,e) do { (m)->function = f; (e) = tcpip_apimsg(m); } while(0) +#define TCPIP_APIMSG_ACK(m) sys_sem_signal(&m->conn->op_completed) +#define TCPIP_APIMSG_ACK_SND(m) sys_sem_signal(&m->conn->snd_op_completed) + +#define TCPIP_NETIFAPI(m) tcpip_netifapi(m) +#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem) +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +/** Function prototype for the init_done function passed to tcpip_init */ +typedef void (*tcpip_init_done_fn)(void *arg); +/** Function prototype for functions passed to tcpip_callback() */ +typedef void (*tcpip_callback_fn)(void *ctx); + +/* Forward declarations */ +struct tcpip_callback_msg; + +void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); + +#if LWIP_NETCONN +err_t tcpip_apimsg(struct api_msg *apimsg); +#endif /* LWIP_NETCONN */ + +err_t tcpip_input(struct pbuf *p, struct netif *inp); + +#if LWIP_NETIF_API +err_t tcpip_netifapi(struct netifapi_msg *netifapimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETIF_API */ + +err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); +#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) + +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg); +err_t tcpip_trycallback(struct tcpip_callback_msg* msg); + +/* free pbufs or heap memory from another context without blocking */ +err_t pbuf_free_callback(struct pbuf *p); +err_t mem_free_callback(void *m); + +#if LWIP_TCPIP_TIMEOUT +err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg); +err_t tcpip_untimeout(sys_timeout_handler h, void *arg); +#endif /* LWIP_TCPIP_TIMEOUT */ + +enum tcpip_msg_type { +#if LWIP_NETCONN + TCPIP_MSG_API, +#endif /* LWIP_NETCONN */ + TCPIP_MSG_INPKT, +#if LWIP_NETIF_API + TCPIP_MSG_NETIFAPI, +#endif /* LWIP_NETIF_API */ +#if LWIP_TCPIP_TIMEOUT + TCPIP_MSG_TIMEOUT, + TCPIP_MSG_UNTIMEOUT, +#endif /* LWIP_TCPIP_TIMEOUT */ + TCPIP_MSG_CALLBACK, + TCPIP_MSG_CALLBACK_STATIC +}; + +struct tcpip_msg { + enum tcpip_msg_type type; + sys_sem_t *sem; + union { +#if LWIP_NETCONN + struct api_msg *apimsg; +#endif /* LWIP_NETCONN */ +#if LWIP_NETIF_API + struct netifapi_msg *netifapimsg; +#endif /* LWIP_NETIF_API */ + struct { + struct pbuf *p; + struct netif *netif; + } inp; + struct { + tcpip_callback_fn function; + void *ctx; + } cb; +#if LWIP_TCPIP_TIMEOUT + struct { + u32_t msecs; + sys_timeout_handler h; + void *arg; + } tmo; +#endif /* LWIP_TCPIP_TIMEOUT */ + } msg; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* !NO_SYS */ + +#endif /* __LWIP_TCPIP_H__ */ diff --git a/include/lwip/lwip/timers.h b/include/lwip/lwip/timers.h index 03612f9e..04e78e0f 100644 --- a/include/lwip/lwip/timers.h +++ b/include/lwip/lwip/timers.h @@ -1,100 +1,100 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * Simon Goldschmidt - * - */ -#ifndef __LWIP_TIMERS_H__ -#define __LWIP_TIMERS_H__ - -#include "lwip/opt.h" - -/* Timers are not supported when NO_SYS==1 and NO_SYS_NO_TIMERS==1 */ -#define LWIP_TIMERS (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) - -#if LWIP_TIMERS - -#include "lwip/err.h" -#if !NO_SYS -#include "lwip/sys.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef LWIP_DEBUG_TIMERNAMES -#ifdef LWIP_DEBUG -#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG -#else /* LWIP_DEBUG */ -#define LWIP_DEBUG_TIMERNAMES 0 -#endif /* LWIP_DEBUG*/ -#endif - -/** Function prototype for a timeout callback function. Register such a function - * using sys_timeout(). - * - * @param arg Additional argument to pass to the function - set up by sys_timeout() - */ -typedef void (* sys_timeout_handler)(void *arg); - -struct sys_timeo { - struct sys_timeo *next; - u32_t time; - sys_timeout_handler h; - void *arg; -#if LWIP_DEBUG_TIMERNAMES - const char* handler_name; -#endif /* LWIP_DEBUG_TIMERNAMES */ -}; - -void sys_timeouts_init(void); - -#if LWIP_DEBUG_TIMERNAMES -void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name); -#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler) -#else /* LWIP_DEBUG_TIMERNAMES */ -void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg); -#endif /* LWIP_DEBUG_TIMERNAMES */ - -void sys_untimeout(sys_timeout_handler handler, void *arg); -#if NO_SYS -void sys_check_timeouts(void); -void sys_restart_timeouts(void); -#else /* NO_SYS */ -void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg); -#endif /* NO_SYS */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TIMERS */ -#endif /* __LWIP_TIMERS_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ +#ifndef __LWIP_TIMERS_H__ +#define __LWIP_TIMERS_H__ + +#include "lwip/opt.h" + +/* Timers are not supported when NO_SYS==1 and NO_SYS_NO_TIMERS==1 */ +#define LWIP_TIMERS (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) + +#if LWIP_TIMERS + +#include "lwip/err.h" +#if !NO_SYS +#include "lwip/sys.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LWIP_DEBUG_TIMERNAMES +#ifdef LWIP_DEBUG +#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG +#else /* LWIP_DEBUG */ +#define LWIP_DEBUG_TIMERNAMES 0 +#endif /* LWIP_DEBUG*/ +#endif + +/** Function prototype for a timeout callback function. Register such a function + * using sys_timeout(). + * + * @param arg Additional argument to pass to the function - set up by sys_timeout() + */ +typedef void (* sys_timeout_handler)(void *arg); + +struct sys_timeo { + struct sys_timeo *next; + u32_t time; + sys_timeout_handler h; + void *arg; +#if LWIP_DEBUG_TIMERNAMES + const char* handler_name; +#endif /* LWIP_DEBUG_TIMERNAMES */ +}; + +void sys_timeouts_init(void); + +#if LWIP_DEBUG_TIMERNAMES +void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name); +#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler) +#else /* LWIP_DEBUG_TIMERNAMES */ +void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg); +#endif /* LWIP_DEBUG_TIMERNAMES */ + +void sys_untimeout(sys_timeout_handler handler, void *arg); +#if NO_SYS +void sys_check_timeouts(void); +void sys_restart_timeouts(void); +#else /* NO_SYS */ +void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg); +#endif /* NO_SYS */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TIMERS */ +#endif /* __LWIP_TIMERS_H__ */ diff --git a/include/lwip/lwip/udp.h b/include/lwip/lwip/udp.h index 85e0fef8..14d5c0ae 100644 --- a/include/lwip/lwip/udp.h +++ b/include/lwip/lwip/udp.h @@ -1,215 +1,215 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __LWIP_UDP_H__ -#define __LWIP_UDP_H__ - -#include "lwip/opt.h" - -#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/ip_addr.h" -#include "lwip/ip.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define UDP_HLEN 8 - -/* Fields are (of course) in network byte order. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct udp_hdr { - PACK_STRUCT_FIELD(u16_t src); - PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ - PACK_STRUCT_FIELD(u16_t len); - PACK_STRUCT_FIELD(u16_t chksum); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define UDP_FLAGS_NOCHKSUM 0x01U -#define UDP_FLAGS_UDPLITE 0x02U -#define UDP_FLAGS_CONNECTED 0x04U -#define UDP_FLAGS_MULTICAST_LOOP 0x08U - -struct udp_pcb; - -/** Function prototype for udp pcb receive callback functions - * addr and port are in same byte order as in the pcb - * The callback is responsible for freeing the pbuf - * if it's not used any more. - * - * ATTENTION: Be aware that 'addr' points into the pbuf 'p' so freeing this pbuf - * makes 'addr' invalid, too. - * - * @param arg user supplied argument (udp_pcb.recv_arg) - * @param pcb the udp_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IP address from which the packet was received - * @param port the remote port from which the packet was received - */ -typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *addr, u16_t port); - -#if LWIP_IPV6 -/** Function prototype for udp pcb IPv6 receive callback functions - * The callback is responsible for freeing the pbuf - * if it's not used any more. - * - * @param arg user supplied argument (udp_pcb.recv_arg) - * @param pcb the udp_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IPv6 address from which the packet was received - * @param port the remote port from which the packet was received - */ -typedef void (*udp_recv_ip6_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, - ip6_addr_t *addr, u16_t port); -#endif /* LWIP_IPV6 */ - -#if LWIP_IPV6 -#define UDP_PCB_RECV_IP6 udp_recv_ip6_fn ip6; -#else -#define UDP_PCB_RECV_IP6 -#endif /* LWIP_IPV6 */ - -struct udp_pcb { -/* Common members of all PCB types */ - IP_PCB; - -/* Protocol specific PCB members */ - - struct udp_pcb *next; - - u8_t flags; - /** ports are in host byte order */ - u16_t local_port, remote_port; - -#if LWIP_IGMP - /** outgoing network interface for multicast packets */ - ip_addr_t multicast_ip; -#endif /* LWIP_IGMP */ - -#if LWIP_UDPLITE - /** used for UDP_LITE only */ - u16_t chksum_len_rx, chksum_len_tx; -#endif /* LWIP_UDPLITE */ - - /** receive callback function */ - union { - udp_recv_fn ip4; - UDP_PCB_RECV_IP6 - }recv; - /** user-supplied argument for the recv callback */ - void *recv_arg; -}; -/* udp_pcbs export for exernal reference (e.g. SNMP agent) */ -extern struct udp_pcb *udp_pcbs; - -/* The following functions is the application layer interface to the - UDP code. */ -struct udp_pcb * udp_new (void); -void udp_remove (struct udp_pcb *pcb); -err_t udp_bind (struct udp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port); -err_t udp_connect (struct udp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port); -void udp_disconnect (struct udp_pcb *pcb); -void udp_recv (struct udp_pcb *pcb, udp_recv_fn recv, - void *recv_arg); -err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *dst_ip, u16_t dst_port, - struct netif *netif); -err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *dst_ip, u16_t dst_port); -err_t udp_send (struct udp_pcb *pcb, struct pbuf *p); - -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP -err_t udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *dst_ip, u16_t dst_port, - struct netif *netif, u8_t have_chksum, - u16_t chksum); -err_t udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, - ip_addr_t *dst_ip, u16_t dst_port, - u8_t have_chksum, u16_t chksum); -err_t udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, - u8_t have_chksum, u16_t chksum); -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - -#define udp_flags(pcb) ((pcb)->flags) -#define udp_setflags(pcb, f) ((pcb)->flags = (f)) - -/* The following functions are the lower layer interface to UDP. */ -void udp_input (struct pbuf *p, struct netif *inp); - -void udp_init (void); - -#if LWIP_IPV6 -struct udp_pcb * udp_new_ip6(void); -#define udp_bind_ip6(pcb, ip6addr, port) \ - udp_bind(pcb, ip6_2_ip(ip6addr), port) -#define udp_connect_ip6(pcb, ip6addr, port) \ - udp_connect(pcb, ip6_2_ip(ip6addr), port) -#define udp_recv_ip6(pcb, recv_ip6_fn, recv_arg) \ - udp_recv(pcb, (udp_recv_fn)recv_ip6_fn, recv_arg) -#define udp_sendto_ip6(pcb, pbuf, ip6addr, port) \ - udp_sendto(pcb, pbuf, ip6_2_ip(ip6addr), port) -#define udp_sendto_if_ip6(pcb, pbuf, ip6addr, port, netif) \ - udp_sendto_if(pcb, pbuf, ip6_2_ip(ip6addr), port, netif) -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP -#define udp_sendto_chksum_ip6(pcb, pbuf, ip6addr, port, have_chk, chksum) \ - udp_sendto_chksum(pcb, pbuf, ip6_2_ip(ip6addr), port, have_chk, chksum) -#define udp_sendto_if_chksum_ip6(pcb, pbuf, ip6addr, port, netif, have_chk, chksum) \ - udp_sendto_if_chksum(pcb, pbuf, ip6_2_ip(ip6addr), port, netif, have_chk, chksum) -#endif /*LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ -#endif /* LWIP_IPV6 */ - -#if UDP_DEBUG -void udp_debug_print(struct udp_hdr *udphdr); -#else -#define udp_debug_print(udphdr) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_UDP */ - -#endif /* __LWIP_UDP_H__ */ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_UDP_H__ +#define __LWIP_UDP_H__ + +#include "lwip/opt.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/ip_addr.h" +#include "lwip/ip.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UDP_HLEN 8 + +/* Fields are (of course) in network byte order. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct udp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ + PACK_STRUCT_FIELD(u16_t len); + PACK_STRUCT_FIELD(u16_t chksum); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define UDP_FLAGS_NOCHKSUM 0x01U +#define UDP_FLAGS_UDPLITE 0x02U +#define UDP_FLAGS_CONNECTED 0x04U +#define UDP_FLAGS_MULTICAST_LOOP 0x08U + +struct udp_pcb; + +/** Function prototype for udp pcb receive callback functions + * addr and port are in same byte order as in the pcb + * The callback is responsible for freeing the pbuf + * if it's not used any more. + * + * ATTENTION: Be aware that 'addr' points into the pbuf 'p' so freeing this pbuf + * makes 'addr' invalid, too. + * + * @param arg user supplied argument (udp_pcb.recv_arg) + * @param pcb the udp_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IP address from which the packet was received + * @param port the remote port from which the packet was received + */ +typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *addr, u16_t port); + +#if LWIP_IPV6 +/** Function prototype for udp pcb IPv6 receive callback functions + * The callback is responsible for freeing the pbuf + * if it's not used any more. + * + * @param arg user supplied argument (udp_pcb.recv_arg) + * @param pcb the udp_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IPv6 address from which the packet was received + * @param port the remote port from which the packet was received + */ +typedef void (*udp_recv_ip6_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, + ip6_addr_t *addr, u16_t port); +#endif /* LWIP_IPV6 */ + +#if LWIP_IPV6 +#define UDP_PCB_RECV_IP6 udp_recv_ip6_fn ip6; +#else +#define UDP_PCB_RECV_IP6 +#endif /* LWIP_IPV6 */ + +struct udp_pcb { +/* Common members of all PCB types */ + IP_PCB; + +/* Protocol specific PCB members */ + + struct udp_pcb *next; + + u8_t flags; + /** ports are in host byte order */ + u16_t local_port, remote_port; + +#if LWIP_IGMP + /** outgoing network interface for multicast packets */ + ip_addr_t multicast_ip; +#endif /* LWIP_IGMP */ + +#if LWIP_UDPLITE + /** used for UDP_LITE only */ + u16_t chksum_len_rx, chksum_len_tx; +#endif /* LWIP_UDPLITE */ + + /** receive callback function */ + union { + udp_recv_fn ip4; + UDP_PCB_RECV_IP6 + }recv; + /** user-supplied argument for the recv callback */ + void *recv_arg; +}; +/* udp_pcbs export for exernal reference (e.g. SNMP agent) */ +extern struct udp_pcb *udp_pcbs; + +/* The following functions is the application layer interface to the + UDP code. */ +struct udp_pcb * udp_new (void); +void udp_remove (struct udp_pcb *pcb); +err_t udp_bind (struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +err_t udp_connect (struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +void udp_disconnect (struct udp_pcb *pcb); +void udp_recv (struct udp_pcb *pcb, udp_recv_fn recv, + void *recv_arg); +err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + struct netif *netif); +err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port); +err_t udp_send (struct udp_pcb *pcb, struct pbuf *p); + +#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP +err_t udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + struct netif *netif, u8_t have_chksum, + u16_t chksum); +err_t udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + u8_t have_chksum, u16_t chksum); +err_t udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, + u8_t have_chksum, u16_t chksum); +#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + +#define udp_flags(pcb) ((pcb)->flags) +#define udp_setflags(pcb, f) ((pcb)->flags = (f)) + +/* The following functions are the lower layer interface to UDP. */ +void udp_input (struct pbuf *p, struct netif *inp); + +void udp_init (void); + +#if LWIP_IPV6 +struct udp_pcb * udp_new_ip6(void); +#define udp_bind_ip6(pcb, ip6addr, port) \ + udp_bind(pcb, ip6_2_ip(ip6addr), port) +#define udp_connect_ip6(pcb, ip6addr, port) \ + udp_connect(pcb, ip6_2_ip(ip6addr), port) +#define udp_recv_ip6(pcb, recv_ip6_fn, recv_arg) \ + udp_recv(pcb, (udp_recv_fn)recv_ip6_fn, recv_arg) +#define udp_sendto_ip6(pcb, pbuf, ip6addr, port) \ + udp_sendto(pcb, pbuf, ip6_2_ip(ip6addr), port) +#define udp_sendto_if_ip6(pcb, pbuf, ip6addr, port, netif) \ + udp_sendto_if(pcb, pbuf, ip6_2_ip(ip6addr), port, netif) +#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP +#define udp_sendto_chksum_ip6(pcb, pbuf, ip6addr, port, have_chk, chksum) \ + udp_sendto_chksum(pcb, pbuf, ip6_2_ip(ip6addr), port, have_chk, chksum) +#define udp_sendto_if_chksum_ip6(pcb, pbuf, ip6addr, port, netif, have_chk, chksum) \ + udp_sendto_if_chksum(pcb, pbuf, ip6_2_ip(ip6addr), port, netif, have_chk, chksum) +#endif /*LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ +#endif /* LWIP_IPV6 */ + +#if UDP_DEBUG +void udp_debug_print(struct udp_hdr *udphdr); +#else +#define udp_debug_print(udphdr) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_UDP */ + +#endif /* __LWIP_UDP_H__ */ diff --git a/include/lwip/lwipopts.h b/include/lwip/lwipopts.h index cdea31f1..e133488c 100644 --- a/include/lwip/lwipopts.h +++ b/include/lwip/lwipopts.h @@ -1,502 +1,502 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef __LWIPOPTS_H__ -#define __LWIPOPTS_H__ - -#define LWIP_ESP8266 - -#define SOCKETS_MT - -//#define SOCKETS_TCP_TRACE -/* - ----------------------------------------------- - ---------- Platform specific locking ---------- - ----------------------------------------------- -*/ -/** - * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain - * critical regions during buffer allocation, deallocation and memory - * allocation and deallocation. - */ -#define SYS_LIGHTWEIGHT_PROT 1 - -/** - * MEMCPY: override this if you have a faster implementation at hand than the - * one included in your C library - */ -#define MEMCPY(dst,src,len) memcpy(dst,src,len) - -/** - * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a - * call to memcpy() if the length is known at compile time and is small. - */ -#define SMEMCPY(dst,src,len) memcpy(dst,src,len) - -#define LWIP_RAND os_random -/* - ------------------------------------ - ---------- Memory options ---------- - ------------------------------------ -*/ -/** - * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library - * instead of the lwip internal allocator. Can save code size if you - * already use it. - */ -#define MEM_LIBC_MALLOC 1 - -/** -* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. -* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution -* speed and usage from interrupts! -*/ -#define MEMP_MEM_MALLOC 1 - -/** - * MEM_ALIGNMENT: should be set to the alignment of the CPU - * 4 byte alignment -> #define MEM_ALIGNMENT 4 - * 2 byte alignment -> #define MEM_ALIGNMENT 2 - */ -#define MEM_ALIGNMENT 4 - -/* - ------------------------------------------------ - ---------- Internal Memory Pool Sizes ---------- - ------------------------------------------------ -*/ -/** - * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. - * (requires the LWIP_TCP option) - */ -#define MEMP_NUM_TCP_PCB 5 //(*(volatile uint32*)0x600011FC) - -/** - * MEMP_NUM_NETCONN: the number of struct netconns. - * (only needed if you use the sequential API, like api_lib.c) - */ -#define MEMP_NUM_NETCONN 10 - -/* - -------------------------------- - ---------- ARP options ------- - -------------------------------- -*/ -/** - * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address - * resolution. By default, only the most recent packet is queued per IP address. - * This is sufficient for most protocols and mainly reduces TCP connection - * startup time. Set this to 1 if you know your application sends more than one - * packet in a row to an IP address that is not in the ARP cache. - */ -#define ARP_QUEUEING 1 - -#if ARP_QUEUEING -#ifdef LWIP_ESP8266 -/** - * Only queue ARP_ENTRY_QUEUE_SIZE pending outgoing packets for ARP entry. - * This limit will be helpful to avoid system running out of memory instantly. - * (eg. within 350ms) - */ -#define ARP_ENTRY_QUEUE_SIZE 3 -#endif /* LWIP_ESP8266 */ -#endif /* ARP_QUEUEING */ -/* - -------------------------------- - ---------- IP options ---------- - -------------------------------- -*/ -/** - * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that - * this option does not affect outgoing packet sizes, which can be controlled - * via IP_FRAG. - */ -#define IP_REASSEMBLY 0 - -/** - * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note - * that this option does not affect incoming packet sizes, which can be - * controlled via IP_REASSEMBLY. - */ -#define IP_FRAG 0 - -/** - * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) - * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived - * in this time, the whole packet is discarded. - */ -#define IP_REASS_MAXAGE 3 - -/** - * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. - * Since the received pbufs are enqueued, be sure to configure - * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive - * packets even if the maximum amount of fragments is enqueued for reassembly! - */ -#define IP_REASS_MAX_PBUFS 10 - -/* - ---------------------------------- - ---------- ICMP options ---------- - ---------------------------------- -*/ - -/* - --------------------------------- - ---------- RAW options ---------- - --------------------------------- -*/ - -/* - ---------------------------------- - ---------- DHCP options ---------- - ---------------------------------- -*/ -/** - * LWIP_DHCP==1: Enable DHCP module. - */ -#define LWIP_DHCP 1 - -#define LWIP_DHCP_BOOTP_FILE 0 - -/** - * DHCP_MAXRTX: Maximum number of retries of current request. - */ -#define DHCP_MAXRTX (*(volatile uint32*)0x600011E0) - -/* - ------------------------------------ - ---------- AUTOIP options ---------- - ------------------------------------ -*/ -/* - ---------------------------------- - ---------- SNMP options ---------- - ---------------------------------- -*/ -/* - ---------------------------------- - ---------- IGMP options ---------- - ---------------------------------- -*/ -/** - * LWIP_IGMP==1: Turn on IGMP module. - */ -#define LWIP_IGMP 1 - -/* - ---------------------------------- - ---------- DNS options ----------- - ---------------------------------- -*/ -/** - * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS - * transport. - */ -#define LWIP_DNS 1 - -/* - --------------------------------- - ---------- UDP options ---------- - --------------------------------- -*/ -/* - --------------------------------- - ---------- TCP options ---------- - --------------------------------- -*/ -/** - * TCP_WND: The size of a TCP window. This must be at least - * (2 * TCP_MSS) for things to work well - */ -//#define TCP_WND (*(volatile uint32*)0x600011F0) - -/** - * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. - * Define to 0 if your device is low on memory. - */ -#define TCP_QUEUE_OOSEQ 0 - -/* - * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all - * events (accept, sent, etc) that happen in the system. - * LWIP_CALLBACK_API==1: The PCB callback function is called directly - * for the event. This is the default. -*/ -#define TCP_MSS 1460 - -/** - * TCP_MAXRTX: Maximum number of retransmissions of data segments. - */ -#define TCP_MAXRTX 12 //(*(volatile uint32*)0x600011E8) - -/** - * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. - */ -#define TCP_SYNMAXRTX 6 //(*(volatile uint32*)0x600011E4) - -/** - * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. - */ -#define TCP_LISTEN_BACKLOG 1 - -/* - ---------------------------------- - ---------- Pbuf options ---------- - ---------------------------------- -*/ - -/* - ------------------------------------------------ - ---------- Network Interfaces options ---------- - ------------------------------------------------ -*/ - -/** - * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname - * field. - */ -#define LWIP_NETIF_HOSTNAME 1 - -/** - * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data - * to be sent into one single pbuf. This is for compatibility with DMA-enabled - * MACs that do not support scatter-gather. - * Beware that this might involve CPU-memcpy before transmitting that would not - * be needed without this flag! Use this only if you need to! - * - * @todo: TCP and IP-frag do not work with this, yet: - */ -#define LWIP_NETIF_TX_SINGLE_PBUF 1 - -/* - ------------------------------------ - ---------- LOOPIF options ---------- - ------------------------------------ -*/ - -/* - ------------------------------------ - ---------- SLIPIF options ---------- - ------------------------------------ -*/ - -/* - ------------------------------------ - ---------- Thread options ---------- - ------------------------------------ -*/ -/** - * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. - */ -#define TCPIP_THREAD_NAME "tiT" - -/** - * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#define TCPIP_THREAD_STACKSIZE 512 //not ok:384 - -/** - * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#define TCPIP_THREAD_PRIO (configMAX_PRIORITIES-5) - -/** - * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when tcpip_init is called. - */ -#define TCPIP_MBOX_SIZE 16 - -/** - * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#define DEFAULT_UDP_RECVMBOX_SIZE 6 - -/** - * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#define DEFAULT_TCP_RECVMBOX_SIZE 6 - -/** - * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when the acceptmbox is created. - */ -#define DEFAULT_ACCEPTMBOX_SIZE 6 - -/* - ---------------------------------------------- - ---------- Sequential layer options ---------- - ---------------------------------------------- -*/ -/** - * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) - * Don't use it if you're not an active lwIP project member - */ -#define LWIP_TCPIP_CORE_LOCKING 0 - -/* - ------------------------------------ - ---------- Socket options ---------- - ------------------------------------ -*/ -/** - * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and - * SO_SNDTIMEO processing. - */ -#define LWIP_SO_SNDTIMEO 1 - -/** - * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and - * SO_RCVTIMEO processing. - */ -#define LWIP_SO_RCVTIMEO 1 - -/** - * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT - * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set - * in seconds. (does not require sockets.c, and will affect tcp.c) - */ -#define LWIP_TCP_KEEPALIVE 1 - -/** - * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. - */ -#define LWIP_SO_RCVBUF 0 - -/** - * SO_REUSE==1: Enable SO_REUSEADDR option. - */ -#define SO_REUSE 0 - -/* - ---------------------------------------- - ---------- Statistics options ---------- - ---------------------------------------- -*/ -/** - * LWIP_STATS==1: Enable statistics collection in lwip_stats. - */ -#define LWIP_STATS 0 - -/* - --------------------------------- - ---------- PPP options ---------- - --------------------------------- -*/ - -/* - -------------------------------------- - ---------- Checksum options ---------- - -------------------------------------- -*/ - -/* - --------------------------------------- - ---------- IPv6 options --------------- - --------------------------------------- -*/ -/** - * LWIP_IPV6==1: Enable IPv6 - */ -#define LWIP_IPV6 1 - -/* - --------------------------------------- - ---------- Hook options --------------- - --------------------------------------- -*/ - -/* - --------------------------------------- - ---------- Debugging options ---------- - --------------------------------------- -*/ -/** - * ETHARP_DEBUG: Enable debugging in etharp.c. - */ -#define ETHARP_DEBUG LWIP_DBG_OFF - -/** - * PBUF_DEBUG: Enable debugging in pbuf.c. - */ -#define PBUF_DEBUG LWIP_DBG_OFF - -/** - * API_LIB_DEBUG: Enable debugging in api_lib.c. - */ -#define API_LIB_DEBUG LWIP_DBG_OFF - -/** - * SOCKETS_DEBUG: Enable debugging in sockets.c. - */ -#define SOCKETS_DEBUG LWIP_DBG_OFF - -/** - * IP_DEBUG: Enable debugging for IP. - */ -#define IP_DEBUG LWIP_DBG_OFF - -/** - * MEMP_DEBUG: Enable debugging in memp.c. - */ -#define MEMP_DEBUG LWIP_DBG_OFF - -/** - * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. - */ -#define TCP_INPUT_DEBUG LWIP_DBG_OFF - -/** - * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. - */ -#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF - -/** - * TCPIP_DEBUG: Enable debugging in tcpip.c. - */ -#define TCPIP_DEBUG LWIP_DBG_OFF - -/** - * DHCP_DEBUG: Enable debugging in dhcp.c. - */ -#define DHCP_DEBUG LWIP_DBG_OFF - -#endif /* __LWIPOPTS_H__ */ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +#define LWIP_ESP8266 + +#define SOCKETS_MT + +//#define SOCKETS_TCP_TRACE +/* + ----------------------------------------------- + ---------- Platform specific locking ---------- + ----------------------------------------------- +*/ +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#define SYS_LIGHTWEIGHT_PROT 1 + +/** + * MEMCPY: override this if you have a faster implementation at hand than the + * one included in your C library + */ +#define MEMCPY(dst,src,len) memcpy(dst,src,len) + +/** + * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a + * call to memcpy() if the length is known at compile time and is small. + */ +#define SMEMCPY(dst,src,len) memcpy(dst,src,len) + +#define LWIP_RAND os_random +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#define MEM_LIBC_MALLOC 1 + +/** +* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. +* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution +* speed and usage from interrupts! +*/ +#define MEMP_MEM_MALLOC 1 + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> #define MEM_ALIGNMENT 4 + * 2 byte alignment -> #define MEM_ALIGNMENT 2 + */ +#define MEM_ALIGNMENT 4 + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ +/** + * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. + * (requires the LWIP_TCP option) + */ +#define MEMP_NUM_TCP_PCB 5 //(*(volatile uint32*)0x600011FC) + +/** + * MEMP_NUM_NETCONN: the number of struct netconns. + * (only needed if you use the sequential API, like api_lib.c) + */ +#define MEMP_NUM_NETCONN 10 + +/* + -------------------------------- + ---------- ARP options ------- + -------------------------------- +*/ +/** + * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address + * resolution. By default, only the most recent packet is queued per IP address. + * This is sufficient for most protocols and mainly reduces TCP connection + * startup time. Set this to 1 if you know your application sends more than one + * packet in a row to an IP address that is not in the ARP cache. + */ +#define ARP_QUEUEING 1 + +#if ARP_QUEUEING +#ifdef LWIP_ESP8266 +/** + * Only queue ARP_ENTRY_QUEUE_SIZE pending outgoing packets for ARP entry. + * This limit will be helpful to avoid system running out of memory instantly. + * (eg. within 350ms) + */ +#define ARP_ENTRY_QUEUE_SIZE 3 +#endif /* LWIP_ESP8266 */ +#endif /* ARP_QUEUEING */ +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ +/** + * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that + * this option does not affect outgoing packet sizes, which can be controlled + * via IP_FRAG. + */ +#define IP_REASSEMBLY 0 + +/** + * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note + * that this option does not affect incoming packet sizes, which can be + * controlled via IP_REASSEMBLY. + */ +#define IP_FRAG 0 + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#define IP_REASS_MAXAGE 3 + +/** + * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. + * Since the received pbufs are enqueued, be sure to configure + * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive + * packets even if the maximum amount of fragments is enqueued for reassembly! + */ +#define IP_REASS_MAX_PBUFS 10 + +/* + ---------------------------------- + ---------- ICMP options ---------- + ---------------------------------- +*/ + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#define LWIP_DHCP 1 + +#define LWIP_DHCP_BOOTP_FILE 0 + +/** + * DHCP_MAXRTX: Maximum number of retries of current request. + */ +#define DHCP_MAXRTX (*(volatile uint32*)0x600011E0) + +/* + ------------------------------------ + ---------- AUTOIP options ---------- + ------------------------------------ +*/ +/* + ---------------------------------- + ---------- SNMP options ---------- + ---------------------------------- +*/ +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#define LWIP_IGMP 1 + +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#define LWIP_DNS 1 + +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +/** + * TCP_WND: The size of a TCP window. This must be at least + * (2 * TCP_MSS) for things to work well + */ +//#define TCP_WND (*(volatile uint32*)0x600011F0) + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#define TCP_QUEUE_OOSEQ 0 + +/* + * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all + * events (accept, sent, etc) that happen in the system. + * LWIP_CALLBACK_API==1: The PCB callback function is called directly + * for the event. This is the default. +*/ +#define TCP_MSS 1460 + +/** + * TCP_MAXRTX: Maximum number of retransmissions of data segments. + */ +#define TCP_MAXRTX 12 //(*(volatile uint32*)0x600011E8) + +/** + * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. + */ +#define TCP_SYNMAXRTX 6 //(*(volatile uint32*)0x600011E4) + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#define TCP_LISTEN_BACKLOG 1 + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ + +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#define LWIP_NETIF_HOSTNAME 1 + +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * to be sent into one single pbuf. This is for compatibility with DMA-enabled + * MACs that do not support scatter-gather. + * Beware that this might involve CPU-memcpy before transmitting that would not + * be needed without this flag! Use this only if you need to! + * + * @todo: TCP and IP-frag do not work with this, yet: + */ +#define LWIP_NETIF_TX_SINGLE_PBUF 1 + +/* + ------------------------------------ + ---------- LOOPIF options ---------- + ------------------------------------ +*/ + +/* + ------------------------------------ + ---------- SLIPIF options ---------- + ------------------------------------ +*/ + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. + */ +#define TCPIP_THREAD_NAME "tiT" + +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define TCPIP_THREAD_STACKSIZE 512 //not ok:384 + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define TCPIP_THREAD_PRIO (configMAX_PRIORITIES-5) + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#define TCPIP_MBOX_SIZE 16 + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_UDP_RECVMBOX_SIZE 6 + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_TCP_RECVMBOX_SIZE 6 + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#define DEFAULT_ACCEPTMBOX_SIZE 6 + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** + * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#define LWIP_TCPIP_CORE_LOCKING 0 + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#define LWIP_SO_SNDTIMEO 1 + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. + */ +#define LWIP_SO_RCVTIMEO 1 + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#define LWIP_TCP_KEEPALIVE 1 + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#define LWIP_SO_RCVBUF 0 + +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#define SO_REUSE 0 + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#define LWIP_STATS 0 + +/* + --------------------------------- + ---------- PPP options ---------- + --------------------------------- +*/ + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ + +/* + --------------------------------------- + ---------- IPv6 options --------------- + --------------------------------------- +*/ +/** + * LWIP_IPV6==1: Enable IPv6 + */ +#define LWIP_IPV6 1 + +/* + --------------------------------------- + ---------- Hook options --------------- + --------------------------------------- +*/ + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +/** + * ETHARP_DEBUG: Enable debugging in etharp.c. + */ +#define ETHARP_DEBUG LWIP_DBG_OFF + +/** + * PBUF_DEBUG: Enable debugging in pbuf.c. + */ +#define PBUF_DEBUG LWIP_DBG_OFF + +/** + * API_LIB_DEBUG: Enable debugging in api_lib.c. + */ +#define API_LIB_DEBUG LWIP_DBG_OFF + +/** + * SOCKETS_DEBUG: Enable debugging in sockets.c. + */ +#define SOCKETS_DEBUG LWIP_DBG_OFF + +/** + * IP_DEBUG: Enable debugging for IP. + */ +#define IP_DEBUG LWIP_DBG_OFF + +/** + * MEMP_DEBUG: Enable debugging in memp.c. + */ +#define MEMP_DEBUG LWIP_DBG_OFF + +/** + * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. + */ +#define TCP_INPUT_DEBUG LWIP_DBG_OFF + +/** + * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. + */ +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF + +/** + * TCPIP_DEBUG: Enable debugging in tcpip.c. + */ +#define TCPIP_DEBUG LWIP_DBG_OFF + +/** + * DHCP_DEBUG: Enable debugging in dhcp.c. + */ +#define DHCP_DEBUG LWIP_DBG_OFF + +#endif /* __LWIPOPTS_H__ */ diff --git a/include/lwip/netif/etharp.h b/include/lwip/netif/etharp.h index aca22887..f1341024 100644 --- a/include/lwip/netif/etharp.h +++ b/include/lwip/netif/etharp.h @@ -1,224 +1,224 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef __NETIF_ETHARP_H__ -#define __NETIF_ETHARP_H__ - -#include "lwip/opt.h" - -#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/ip.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ETHARP_HWADDR_LEN -#define ETHARP_HWADDR_LEN 6 -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct eth_addr { - PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** Ethernet header */ -struct eth_hdr { -#if ETH_PAD_SIZE - PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]); -#endif - PACK_STRUCT_FIELD(struct eth_addr dest); - PACK_STRUCT_FIELD(struct eth_addr src); - PACK_STRUCT_FIELD(u16_t type); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) - -#if ETHARP_SUPPORT_VLAN - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** VLAN header inserted between ethernet header and payload - * if 'type' in ethernet header is ETHTYPE_VLAN. - * See IEEE802.Q */ -struct eth_vlan_hdr { - PACK_STRUCT_FIELD(u16_t prio_vid); - PACK_STRUCT_FIELD(u16_t tpid); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_VLAN_HDR 4 -#define VLAN_ID(vlan_hdr) (htons((vlan_hdr)->prio_vid) & 0xFFF) - -#endif /* ETHARP_SUPPORT_VLAN */ - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** the ARP message, see RFC 826 ("Packet format") */ -struct etharp_hdr { - PACK_STRUCT_FIELD(u16_t hwtype); - PACK_STRUCT_FIELD(u16_t proto); - PACK_STRUCT_FIELD(u8_t hwlen); - PACK_STRUCT_FIELD(u8_t protolen); - PACK_STRUCT_FIELD(u16_t opcode); - PACK_STRUCT_FIELD(struct eth_addr shwaddr); - PACK_STRUCT_FIELD(struct ip_addr2 sipaddr); - PACK_STRUCT_FIELD(struct eth_addr dhwaddr); - PACK_STRUCT_FIELD(struct ip_addr2 dipaddr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_ETHARP_HDR 28 -#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR) - -/** 5 seconds period */ -#define ARP_TMR_INTERVAL 5000 - -#define ETHTYPE_ARP 0x0806U -#define ETHTYPE_IP 0x0800U -#define ETHTYPE_VLAN 0x8100U -#define ETHTYPE_IPV6 0x86DDU -#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */ -#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */ -#define ETHTYPE_PAE 0x888e - -/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables - * or known to be 32-bit aligned within the protocol header. */ -#ifndef ETHADDR32_COPY -#define ETHADDR32_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN) -#endif - -/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local - * variables and known to be 16-bit aligned within the protocol header. */ -#ifndef ETHADDR16_COPY -#define ETHADDR16_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN) -#endif - -#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ - -/** ARP message types (opcodes) */ -#define ARP_REQUEST 1 -#define ARP_REPLY 2 - -/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type) - * to a filter function that returns the correct netif when using multiple - * netifs on one hardware interface where the netif's low-level receive - * routine cannot decide for the correct netif (e.g. when mapping multiple - * IP addresses to one hardware interface). - */ -#ifndef LWIP_ARP_FILTER_NETIF -#define LWIP_ARP_FILTER_NETIF 0 -#endif - -#if ARP_QUEUEING -/** struct for queueing outgoing packets for unknown address - * defined here to be accessed by memp.h - */ -struct etharp_q_entry { - struct etharp_q_entry *next; - struct pbuf *p; -}; -#endif /* ARP_QUEUEING */ - -#define etharp_init() /* Compatibility define, not init needed. */ -void etharp_tmr(void); -s8_t etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, - struct eth_addr **eth_ret, ip_addr_t **ip_ret); -err_t etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr); -err_t etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q); -err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr); -/** For Ethernet network interfaces, we might want to send "gratuitous ARP"; - * this is an ARP packet sent by a node in order to spontaneously cause other - * nodes to update an entry in their ARP cache. - * From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */ -#define etharp_gratuitous(netif) etharp_request((netif), &(netif)->ip_addr) -void etharp_cleanup_netif(struct netif *netif); - -#if ETHARP_SUPPORT_STATIC_ENTRIES -err_t etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr); -err_t etharp_remove_static_entry(ip_addr_t *ipaddr); -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - -#if LWIP_AUTOIP -err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, - const struct eth_addr *ethdst_addr, - const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, - const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, - const u16_t opcode); -#endif /* LWIP_AUTOIP */ - -#endif /* LWIP_ARP */ - -err_t ethernet_input(struct pbuf *p, struct netif *netif); - -#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0) - -extern const struct eth_addr ethbroadcast, ethzero; - -#endif /* LWIP_ARP || LWIP_ETHERNET */ - -#ifdef __cplusplus -} -#endif - -#endif /* __NETIF_ARP_H__ */ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2003-2004 Leon Woestenberg + * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __NETIF_ETHARP_H__ +#define __NETIF_ETHARP_H__ + +#include "lwip/opt.h" + +#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ETHARP_HWADDR_LEN +#define ETHARP_HWADDR_LEN 6 +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct eth_addr { + PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** Ethernet header */ +struct eth_hdr { +#if ETH_PAD_SIZE + PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]); +#endif + PACK_STRUCT_FIELD(struct eth_addr dest); + PACK_STRUCT_FIELD(struct eth_addr src); + PACK_STRUCT_FIELD(u16_t type); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) + +#if ETHARP_SUPPORT_VLAN + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** VLAN header inserted between ethernet header and payload + * if 'type' in ethernet header is ETHTYPE_VLAN. + * See IEEE802.Q */ +struct eth_vlan_hdr { + PACK_STRUCT_FIELD(u16_t prio_vid); + PACK_STRUCT_FIELD(u16_t tpid); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_VLAN_HDR 4 +#define VLAN_ID(vlan_hdr) (htons((vlan_hdr)->prio_vid) & 0xFFF) + +#endif /* ETHARP_SUPPORT_VLAN */ + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** the ARP message, see RFC 826 ("Packet format") */ +struct etharp_hdr { + PACK_STRUCT_FIELD(u16_t hwtype); + PACK_STRUCT_FIELD(u16_t proto); + PACK_STRUCT_FIELD(u8_t hwlen); + PACK_STRUCT_FIELD(u8_t protolen); + PACK_STRUCT_FIELD(u16_t opcode); + PACK_STRUCT_FIELD(struct eth_addr shwaddr); + PACK_STRUCT_FIELD(struct ip_addr2 sipaddr); + PACK_STRUCT_FIELD(struct eth_addr dhwaddr); + PACK_STRUCT_FIELD(struct ip_addr2 dipaddr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETHARP_HDR 28 +#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR) + +/** 5 seconds period */ +#define ARP_TMR_INTERVAL 5000 + +#define ETHTYPE_ARP 0x0806U +#define ETHTYPE_IP 0x0800U +#define ETHTYPE_VLAN 0x8100U +#define ETHTYPE_IPV6 0x86DDU +#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */ +#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */ +#define ETHTYPE_PAE 0x888e + +/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables + * or known to be 32-bit aligned within the protocol header. */ +#ifndef ETHADDR32_COPY +#define ETHADDR32_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN) +#endif + +/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local + * variables and known to be 16-bit aligned within the protocol header. */ +#ifndef ETHADDR16_COPY +#define ETHADDR16_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN) +#endif + +#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ + +/** ARP message types (opcodes) */ +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type) + * to a filter function that returns the correct netif when using multiple + * netifs on one hardware interface where the netif's low-level receive + * routine cannot decide for the correct netif (e.g. when mapping multiple + * IP addresses to one hardware interface). + */ +#ifndef LWIP_ARP_FILTER_NETIF +#define LWIP_ARP_FILTER_NETIF 0 +#endif + +#if ARP_QUEUEING +/** struct for queueing outgoing packets for unknown address + * defined here to be accessed by memp.h + */ +struct etharp_q_entry { + struct etharp_q_entry *next; + struct pbuf *p; +}; +#endif /* ARP_QUEUEING */ + +#define etharp_init() /* Compatibility define, not init needed. */ +void etharp_tmr(void); +s8_t etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, + struct eth_addr **eth_ret, ip_addr_t **ip_ret); +err_t etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr); +err_t etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q); +err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr); +/** For Ethernet network interfaces, we might want to send "gratuitous ARP"; + * this is an ARP packet sent by a node in order to spontaneously cause other + * nodes to update an entry in their ARP cache. + * From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */ +#define etharp_gratuitous(netif) etharp_request((netif), &(netif)->ip_addr) +void etharp_cleanup_netif(struct netif *netif); + +#if ETHARP_SUPPORT_STATIC_ENTRIES +err_t etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr); +err_t etharp_remove_static_entry(ip_addr_t *ipaddr); +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + +#if LWIP_AUTOIP +err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, + const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, + const u16_t opcode); +#endif /* LWIP_AUTOIP */ + +#endif /* LWIP_ARP */ + +err_t ethernet_input(struct pbuf *p, struct netif *netif); + +#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0) + +extern const struct eth_addr ethbroadcast, ethzero; + +#endif /* LWIP_ARP || LWIP_ETHERNET */ + +#ifdef __cplusplus +} +#endif + +#endif /* __NETIF_ARP_H__ */ diff --git a/include/lwip/netif/ppp_oe.h b/include/lwip/netif/ppp_oe.h index 67d8fe0b..e1cdfa51 100644 --- a/include/lwip/netif/ppp_oe.h +++ b/include/lwip/netif/ppp_oe.h @@ -1,190 +1,190 @@ -/***************************************************************************** -* ppp_oe.h - PPP Over Ethernet implementation for lwIP. -* -* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 06-01-01 Marc Boucher -* Ported to lwIP. -*****************************************************************************/ - - - -/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ - -/*- - * Copyright (c) 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Martin Husemann . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef PPP_OE_H -#define PPP_OE_H - -#include "lwip/opt.h" - -#if PPPOE_SUPPORT > 0 - -#include "netif/etharp.h" - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppoehdr { - PACK_STRUCT_FIELD(u8_t vertype); - PACK_STRUCT_FIELD(u8_t code); - PACK_STRUCT_FIELD(u16_t session); - PACK_STRUCT_FIELD(u16_t plen); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppoetag { - PACK_STRUCT_FIELD(u16_t tag); - PACK_STRUCT_FIELD(u16_t len); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -#define PPPOE_STATE_INITIAL 0 -#define PPPOE_STATE_PADI_SENT 1 -#define PPPOE_STATE_PADR_SENT 2 -#define PPPOE_STATE_SESSION 3 -#define PPPOE_STATE_CLOSING 4 -/* passive */ -#define PPPOE_STATE_PADO_SENT 1 - -#define PPPOE_HEADERLEN sizeof(struct pppoehdr) -#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ - -#define PPPOE_TAG_EOL 0x0000 /* end of list */ -#define PPPOE_TAG_SNAME 0x0101 /* service name */ -#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ -#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ -#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ -#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ -#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ -#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ -#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ -#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ - -#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ -#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ -#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ -#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ -#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ - -#ifndef ETHERMTU -#define ETHERMTU 1500 -#endif - -/* two byte PPP protocol discriminator, then IP data */ -#define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2) - -#ifndef PPPOE_MAX_AC_COOKIE_LEN -#define PPPOE_MAX_AC_COOKIE_LEN 64 -#endif - -struct pppoe_softc { - struct pppoe_softc *next; - struct netif *sc_ethif; /* ethernet interface we are using */ - int sc_pd; /* ppp unit number */ - void (*sc_linkStatusCB)(int pd, int up); - - int sc_state; /* discovery phase or session connected */ - struct eth_addr sc_dest; /* hardware address of concentrator */ - u16_t sc_session; /* PPPoE session id */ - -#ifdef PPPOE_TODO - char *sc_service_name; /* if != NULL: requested name of service */ - char *sc_concentrator_name; /* if != NULL: requested concentrator id */ -#endif /* PPPOE_TODO */ - u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */ - size_t sc_ac_cookie_len; /* length of cookie data */ -#ifdef PPPOE_SERVER - u8_t *sc_hunique; /* content of host unique we must echo back */ - size_t sc_hunique_len; /* length of host unique */ -#endif - int sc_padi_retried; /* number of PADI retries already done */ - int sc_padr_retried; /* number of PADR retries already done */ -}; - - -#define pppoe_init() /* compatibility define, no initialization needed */ - -err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr); -err_t pppoe_destroy(struct netif *ifp); - -int pppoe_connect(struct pppoe_softc *sc); -void pppoe_disconnect(struct pppoe_softc *sc); - -void pppoe_disc_input(struct netif *netif, struct pbuf *p); -void pppoe_data_input(struct netif *netif, struct pbuf *p); - -err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); - -/** used in ppp.c */ -#define PPPOE_HDRLEN (sizeof(struct eth_hdr) + PPPOE_HEADERLEN) - -#endif /* PPPOE_SUPPORT */ - -#endif /* PPP_OE_H */ +/***************************************************************************** +* ppp_oe.h - PPP Over Ethernet implementation for lwIP. +* +* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 06-01-01 Marc Boucher +* Ported to lwIP. +*****************************************************************************/ + + + +/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef PPP_OE_H +#define PPP_OE_H + +#include "lwip/opt.h" + +#if PPPOE_SUPPORT > 0 + +#include "netif/etharp.h" + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppoehdr { + PACK_STRUCT_FIELD(u8_t vertype); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t session); + PACK_STRUCT_FIELD(u16_t plen); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppoetag { + PACK_STRUCT_FIELD(u16_t tag); + PACK_STRUCT_FIELD(u16_t len); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +#define PPPOE_STATE_INITIAL 0 +#define PPPOE_STATE_PADI_SENT 1 +#define PPPOE_STATE_PADR_SENT 2 +#define PPPOE_STATE_SESSION 3 +#define PPPOE_STATE_CLOSING 4 +/* passive */ +#define PPPOE_STATE_PADO_SENT 1 + +#define PPPOE_HEADERLEN sizeof(struct pppoehdr) +#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ + +#define PPPOE_TAG_EOL 0x0000 /* end of list */ +#define PPPOE_TAG_SNAME 0x0101 /* service name */ +#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ +#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ +#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ +#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ +#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ +#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ +#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ +#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ + +#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ +#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ +#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ +#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ +#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ + +#ifndef ETHERMTU +#define ETHERMTU 1500 +#endif + +/* two byte PPP protocol discriminator, then IP data */ +#define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2) + +#ifndef PPPOE_MAX_AC_COOKIE_LEN +#define PPPOE_MAX_AC_COOKIE_LEN 64 +#endif + +struct pppoe_softc { + struct pppoe_softc *next; + struct netif *sc_ethif; /* ethernet interface we are using */ + int sc_pd; /* ppp unit number */ + void (*sc_linkStatusCB)(int pd, int up); + + int sc_state; /* discovery phase or session connected */ + struct eth_addr sc_dest; /* hardware address of concentrator */ + u16_t sc_session; /* PPPoE session id */ + +#ifdef PPPOE_TODO + char *sc_service_name; /* if != NULL: requested name of service */ + char *sc_concentrator_name; /* if != NULL: requested concentrator id */ +#endif /* PPPOE_TODO */ + u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */ + size_t sc_ac_cookie_len; /* length of cookie data */ +#ifdef PPPOE_SERVER + u8_t *sc_hunique; /* content of host unique we must echo back */ + size_t sc_hunique_len; /* length of host unique */ +#endif + int sc_padi_retried; /* number of PADI retries already done */ + int sc_padr_retried; /* number of PADR retries already done */ +}; + + +#define pppoe_init() /* compatibility define, no initialization needed */ + +err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr); +err_t pppoe_destroy(struct netif *ifp); + +int pppoe_connect(struct pppoe_softc *sc); +void pppoe_disconnect(struct pppoe_softc *sc); + +void pppoe_disc_input(struct netif *netif, struct pbuf *p); +void pppoe_data_input(struct netif *netif, struct pbuf *p); + +err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); + +/** used in ppp.c */ +#define PPPOE_HDRLEN (sizeof(struct eth_hdr) + PPPOE_HEADERLEN) + +#endif /* PPPOE_SUPPORT */ + +#endif /* PPP_OE_H */ diff --git a/include/lwip/netif/slipif.h b/include/lwip/netif/slipif.h index 9689c3f3..7b6ce5e2 100644 --- a/include/lwip/netif/slipif.h +++ b/include/lwip/netif/slipif.h @@ -1,81 +1,81 @@ -/* - * Copyright (c) 2001, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef __NETIF_SLIPIF_H__ -#define __NETIF_SLIPIF_H__ - -#include "lwip/opt.h" -#include "lwip/netif.h" - -/** Set this to 1 to start a thread that blocks reading on the serial line - * (using sio_read()). - */ -#ifndef SLIP_USE_RX_THREAD -#define SLIP_USE_RX_THREAD !NO_SYS -#endif - -/** Set this to 1 to enable functions to pass in RX bytes from ISR context. - * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled - * packets on a queue, which is fed into lwIP from slipif_poll(). - * If disabled, slipif_poll() polls the serila line (using sio_tryread()). - */ -#ifndef SLIP_RX_FROM_ISR -#define SLIP_RX_FROM_ISR 0 -#endif - -/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets - * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available. - * If disabled, packets will be dropped if more than one packet is received. - */ -#ifndef SLIP_RX_QUEUE -#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -err_t slipif_init(struct netif * netif); -void slipif_poll(struct netif *netif); -#if SLIP_RX_FROM_ISR -void slipif_process_rxqueue(struct netif *netif); -void slipif_received_byte(struct netif *netif, u8_t data); -void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len); -#endif /* SLIP_RX_FROM_ISR */ - -#ifdef __cplusplus -} -#endif - -#endif - +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __NETIF_SLIPIF_H__ +#define __NETIF_SLIPIF_H__ + +#include "lwip/opt.h" +#include "lwip/netif.h" + +/** Set this to 1 to start a thread that blocks reading on the serial line + * (using sio_read()). + */ +#ifndef SLIP_USE_RX_THREAD +#define SLIP_USE_RX_THREAD !NO_SYS +#endif + +/** Set this to 1 to enable functions to pass in RX bytes from ISR context. + * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled + * packets on a queue, which is fed into lwIP from slipif_poll(). + * If disabled, slipif_poll() polls the serila line (using sio_tryread()). + */ +#ifndef SLIP_RX_FROM_ISR +#define SLIP_RX_FROM_ISR 0 +#endif + +/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets + * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available. + * If disabled, packets will be dropped if more than one packet is received. + */ +#ifndef SLIP_RX_QUEUE +#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +err_t slipif_init(struct netif * netif); +void slipif_poll(struct netif *netif); +#if SLIP_RX_FROM_ISR +void slipif_process_rxqueue(struct netif *netif); +void slipif_received_byte(struct netif *netif, u8_t data); +void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len); +#endif /* SLIP_RX_FROM_ISR */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/lwip/posix/netdb.h b/include/lwip/posix/netdb.h index 8fc2596a..7134032d 100644 --- a/include/lwip/posix/netdb.h +++ b/include/lwip/posix/netdb.h @@ -1,33 +1,33 @@ -/** - * @file - * This file is a posix wrapper for lwip/netdb.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/netdb.h" +/** + * @file + * This file is a posix wrapper for lwip/netdb.h. + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/netdb.h" diff --git a/include/lwip/posix/sys/socket.h b/include/lwip/posix/sys/socket.h index 5d2ab84c..f7c7066e 100644 --- a/include/lwip/posix/sys/socket.h +++ b/include/lwip/posix/sys/socket.h @@ -1,33 +1,33 @@ -/** - * @file - * This file is a posix wrapper for lwip/sockets.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/sockets.h" +/** + * @file + * This file is a posix wrapper for lwip/sockets.h. + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/sockets.h" diff --git a/include/nopoll/nopoll_win32.h b/include/nopoll/nopoll_win32.h index 5b1d589d..be85f80c 100644 --- a/include/nopoll/nopoll_win32.h +++ b/include/nopoll/nopoll_win32.h @@ -1,66 +1,66 @@ -/* - * LibNoPoll: A websocket library - * Copyright (C) 2013 Advanced Software Production Line, S.L. - * - * This program 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free - * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - * - * You may find a copy of the license under this software is released - * at COPYING file. This is LGPL software: you are welcome to develop - * proprietary applications using this library without any royalty or - * fee but returning back any change, improvement or addition in the - * form of source code, project image, documentation patches, etc. - * - * For commercial support on build Websocket enabled solutions - * contact us: - * - * Postal address: - * Advanced Software Production Line, S.L. - * Edificio Alius A, Oficina 102, - * C/ Antonio Suarez Nº 10, - * Alcalá de Henares 28802 Madrid - * Spain - * - * Email address: - * info@aspl.es - http://www.aspl.es/nopoll - */ - -#ifndef __NOPOLL_WIN32_H__ -#define __NOPOLL_WIN32_H__ - -#include - -BEGIN_C_DECLS - -int nopoll_win32_init (noPollCtx * ctx); - -int nopoll_win32_nonblocking_enable (NOPOLL_SOCKET socket); - -int nopoll_win32_blocking_enable (NOPOLL_SOCKET socket); - -/* gettimeofday support on windows */ -int nopoll_win32_gettimeofday (struct timeval *tv, noPollPtr notUsed); - -BOOL APIENTRY DllMain (HINSTANCE hInst, - DWORD reason, - LPVOID reserved); - -#if !defined(EINPROGRESS) -#define EINPROGRESS (WSAEINPROGRESS) -#endif - -END_C_DECLS - -#endif +/* + * LibNoPoll: A websocket library + * Copyright (C) 2013 Advanced Software Production Line, S.L. + * + * This program 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * You may find a copy of the license under this software is released + * at COPYING file. This is LGPL software: you are welcome to develop + * proprietary applications using this library without any royalty or + * fee but returning back any change, improvement or addition in the + * form of source code, project image, documentation patches, etc. + * + * For commercial support on build Websocket enabled solutions + * contact us: + * + * Postal address: + * Advanced Software Production Line, S.L. + * Edificio Alius A, Oficina 102, + * C/ Antonio Suarez Nº 10, + * Alcalá de Henares 28802 Madrid + * Spain + * + * Email address: + * info@aspl.es - http://www.aspl.es/nopoll + */ + +#ifndef __NOPOLL_WIN32_H__ +#define __NOPOLL_WIN32_H__ + +#include + +BEGIN_C_DECLS + +int nopoll_win32_init (noPollCtx * ctx); + +int nopoll_win32_nonblocking_enable (NOPOLL_SOCKET socket); + +int nopoll_win32_blocking_enable (NOPOLL_SOCKET socket); + +/* gettimeofday support on windows */ +int nopoll_win32_gettimeofday (struct timeval *tv, noPollPtr notUsed); + +BOOL APIENTRY DllMain (HINSTANCE hInst, + DWORD reason, + LPVOID reserved); + +#if !defined(EINPROGRESS) +#define EINPROGRESS (WSAEINPROGRESS) +#endif + +END_C_DECLS + +#endif diff --git a/include/openssl/internal/ssl_cert.h b/include/openssl/internal/ssl_cert.h old mode 100755 new mode 100644 diff --git a/include/openssl/internal/ssl_lib.h b/include/openssl/internal/ssl_lib.h old mode 100755 new mode 100644 diff --git a/include/openssl/internal/ssl_methods.h b/include/openssl/internal/ssl_methods.h old mode 100755 new mode 100644 diff --git a/include/openssl/internal/ssl_pkey.h b/include/openssl/internal/ssl_pkey.h old mode 100755 new mode 100644 diff --git a/include/openssl/internal/ssl_stack.h b/include/openssl/internal/ssl_stack.h old mode 100755 new mode 100644 diff --git a/include/openssl/internal/ssl_types.h b/include/openssl/internal/ssl_types.h old mode 100755 new mode 100644 diff --git a/include/openssl/internal/ssl_x509.h b/include/openssl/internal/ssl_x509.h old mode 100755 new mode 100644 diff --git a/include/openssl/internal/x509_vfy.h b/include/openssl/internal/x509_vfy.h index d5b0d1a2..fec367d5 100644 --- a/include/openssl/internal/x509_vfy.h +++ b/include/openssl/internal/x509_vfy.h @@ -1,111 +1,111 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _X509_VFY_H_ -#define _X509_VFY_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#define X509_V_OK 0 -#define X509_V_ERR_UNSPECIFIED 1 -#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 -#define X509_V_ERR_UNABLE_TO_GET_CRL 3 -#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 -#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 -#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 -#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 -#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 -#define X509_V_ERR_CERT_NOT_YET_VALID 9 -#define X509_V_ERR_CERT_HAS_EXPIRED 10 -#define X509_V_ERR_CRL_NOT_YET_VALID 11 -#define X509_V_ERR_CRL_HAS_EXPIRED 12 -#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 -#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 -#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 -#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 -#define X509_V_ERR_OUT_OF_MEM 17 -#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 -#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 -#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 -#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 -#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 -#define X509_V_ERR_CERT_REVOKED 23 -#define X509_V_ERR_INVALID_CA 24 -#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 -#define X509_V_ERR_INVALID_PURPOSE 26 -#define X509_V_ERR_CERT_UNTRUSTED 27 -#define X509_V_ERR_CERT_REJECTED 28 -/* These are 'informational' when looking for issuer cert */ -#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 -#define X509_V_ERR_AKID_SKID_MISMATCH 30 -#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 -#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 -#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 -#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 -#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 -#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 -#define X509_V_ERR_INVALID_NON_CA 37 -#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 -#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 -#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 -#define X509_V_ERR_INVALID_EXTENSION 41 -#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 -#define X509_V_ERR_NO_EXPLICIT_POLICY 43 -#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 -#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 -#define X509_V_ERR_UNNESTED_RESOURCE 46 -#define X509_V_ERR_PERMITTED_VIOLATION 47 -#define X509_V_ERR_EXCLUDED_VIOLATION 48 -#define X509_V_ERR_SUBTREE_MINMAX 49 -/* The application is not happy */ -#define X509_V_ERR_APPLICATION_VERIFICATION 50 -#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 -#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 -#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 -#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 -/* Another issuer check debug option */ -#define X509_V_ERR_PATH_LOOP 55 -/* Suite B mode algorithm violation */ -#define X509_V_ERR_SUITE_B_INVALID_VERSION 56 -#define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 -#define X509_V_ERR_SUITE_B_INVALID_CURVE 58 -#define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 -#define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 -#define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 -/* Host, email and IP check errors */ -#define X509_V_ERR_HOSTNAME_MISMATCH 62 -#define X509_V_ERR_EMAIL_MISMATCH 63 -#define X509_V_ERR_IP_ADDRESS_MISMATCH 64 -/* DANE TLSA errors */ -#define X509_V_ERR_DANE_NO_MATCH 65 -/* security level errors */ -#define X509_V_ERR_EE_KEY_TOO_SMALL 66 -#define X509_V_ERR_CA_KEY_TOO_SMALL 67 -#define X509_V_ERR_CA_MD_TOO_WEAK 68 -/* Caller error */ -#define X509_V_ERR_INVALID_CALL 69 -/* Issuer lookup error */ -#define X509_V_ERR_STORE_LOOKUP 70 -/* Certificate transparency */ -#define X509_V_ERR_NO_VALID_SCTS 71 - -#define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 - -#ifdef __cplusplus -} -#endif - -#endif +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +#ifndef _X509_VFY_H_ +#define _X509_VFY_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define X509_V_OK 0 +#define X509_V_ERR_UNSPECIFIED 1 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +#define X509_V_ERR_UNABLE_TO_GET_CRL 3 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +#define X509_V_ERR_CERT_NOT_YET_VALID 9 +#define X509_V_ERR_CERT_HAS_EXPIRED 10 +#define X509_V_ERR_CRL_NOT_YET_VALID 11 +#define X509_V_ERR_CRL_HAS_EXPIRED 12 +#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +#define X509_V_ERR_OUT_OF_MEM 17 +#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +#define X509_V_ERR_CERT_REVOKED 23 +#define X509_V_ERR_INVALID_CA 24 +#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +#define X509_V_ERR_INVALID_PURPOSE 26 +#define X509_V_ERR_CERT_UNTRUSTED 27 +#define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +#define X509_V_ERR_AKID_SKID_MISMATCH 30 +#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 +#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +#define X509_V_ERR_INVALID_NON_CA 37 +#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 +#define X509_V_ERR_INVALID_EXTENSION 41 +#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +#define X509_V_ERR_NO_EXPLICIT_POLICY 43 +#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 +#define X509_V_ERR_UNNESTED_RESOURCE 46 +#define X509_V_ERR_PERMITTED_VIOLATION 47 +#define X509_V_ERR_EXCLUDED_VIOLATION 48 +#define X509_V_ERR_SUBTREE_MINMAX 49 +/* The application is not happy */ +#define X509_V_ERR_APPLICATION_VERIFICATION 50 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 +/* Another issuer check debug option */ +#define X509_V_ERR_PATH_LOOP 55 +/* Suite B mode algorithm violation */ +#define X509_V_ERR_SUITE_B_INVALID_VERSION 56 +#define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 +#define X509_V_ERR_SUITE_B_INVALID_CURVE 58 +#define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 +#define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 +#define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 +/* Host, email and IP check errors */ +#define X509_V_ERR_HOSTNAME_MISMATCH 62 +#define X509_V_ERR_EMAIL_MISMATCH 63 +#define X509_V_ERR_IP_ADDRESS_MISMATCH 64 +/* DANE TLSA errors */ +#define X509_V_ERR_DANE_NO_MATCH 65 +/* security level errors */ +#define X509_V_ERR_EE_KEY_TOO_SMALL 66 +#define X509_V_ERR_CA_KEY_TOO_SMALL 67 +#define X509_V_ERR_CA_MD_TOO_WEAK 68 +/* Caller error */ +#define X509_V_ERR_INVALID_CALL 69 +/* Issuer lookup error */ +#define X509_V_ERR_STORE_LOOKUP 70 +/* Certificate transparency */ +#define X509_V_ERR_NO_VALID_SCTS 71 + +#define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/openssl/openssl/ssl.h b/include/openssl/openssl/ssl.h old mode 100755 new mode 100644 index 39d4bf73..e568d3c9 --- a/include/openssl/openssl/ssl.h +++ b/include/openssl/openssl/ssl.h @@ -1,1755 +1,1755 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_H_ -#define _SSL_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "internal/ssl_x509.h" -#include "internal/ssl_pkey.h" - -/* -{ -*/ - -/** - * @brief create a SSL context - * - * @param method - the SSL context method point - * - * @return the context point - */ -SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); - -/** - * @brief free a SSL context - * - * @param method - the SSL context point - * - * @return none - */ -void SSL_CTX_free(SSL_CTX *ctx); - -/** - * @brief create a SSL - * - * @param ctx - the SSL context point - * - * @return the SSL point - */ -SSL* SSL_new(SSL_CTX *ctx); - -/** - * @brief free the SSL - * - * @param ssl - the SSL point - * - * @return none - */ -void SSL_free(SSL *ssl); - -/** - * @brief connect to the remote SSL server - * - * @param ssl - the SSL point - * - * @return result - * 1 : OK - * -1 : failed - */ -int SSL_connect(SSL *ssl); - -/** - * @brief accept the remote connection - * - * @param ssl - the SSL point - * - * @return result - * 1 : OK - * -1 : failed - */ -int SSL_accept(SSL *ssl); - -/** - * @brief read data from to remote - * - * @param ssl - the SSL point which has been connected - * @param buffer - the received data buffer point - * @param len - the received data length - * - * @return result - * > 0 : OK, and return received data bytes - * = 0 : connection is closed - * < 0 : an error catch - */ -int SSL_read(SSL *ssl, void *buffer, int len); - -/** - * @brief send the data to remote - * - * @param ssl - the SSL point which has been connected - * @param buffer - the send data buffer point - * @param len - the send data length - * - * @return result - * > 0 : OK, and return sent data bytes - * = 0 : connection is closed - * < 0 : an error catch - */ -int SSL_write(SSL *ssl, const void *buffer, int len); - -/** - * @brief get the verifying result of the SSL certification - * - * @param ssl - the SSL point - * - * @return the result of verifying - */ -long SSL_get_verify_result(const SSL *ssl); - -/** - * @brief shutdown the connection - * - * @param ssl - the SSL point - * - * @return result - * 1 : OK - * 0 : shutdown is not finished - * -1 : an error catch - */ -int SSL_shutdown(SSL *ssl); - -/** - * @brief bind the socket file description into the SSL - * - * @param ssl - the SSL point - * @param fd - socket handle - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_set_fd(SSL *ssl, int fd); - -/** - * @brief These functions load the private key into the SSL_CTX or SSL object - * - * @param ctx - the SSL context point - * @param pkey - private key object point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); - -/** - * @brief These functions load the certification into the SSL_CTX or SSL object - * - * @param ctx - the SSL context point - * @param pkey - certification object point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the SSLV2.3 version SSL context client method - */ -const SSL_METHOD* SSLv23_client_method(void); - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the TLSV1.0 version SSL context client method - */ -const SSL_METHOD* TLSv1_client_method(void); - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the SSLV1.0 version SSL context client method - */ -const SSL_METHOD* SSLv3_client_method(void); - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the TLSV1.1 version SSL context client method - */ -const SSL_METHOD* TLSv1_1_client_method(void); - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the TLSV1.2 version SSL context client method - */ -const SSL_METHOD* TLSv1_2_client_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLS any version SSL context client method - */ -const SSL_METHOD* TLS_client_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the SSLV2.3 version SSL context server method - */ -const SSL_METHOD* SSLv23_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLSV1.1 version SSL context server method - */ -const SSL_METHOD* TLSv1_1_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLSV1.2 version SSL context server method - */ -const SSL_METHOD* TLSv1_2_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLSV1.0 version SSL context server method - */ -const SSL_METHOD* TLSv1_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the SSLV3.0 version SSL context server method - */ -const SSL_METHOD* SSLv3_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLS any version SSL context server method - */ -const SSL_METHOD* TLS_server_method(void); - - -/** - * @brief set the SSL context ALPN select callback function - * - * @param ctx - SSL context point - * @param cb - ALPN select callback function - * @param arg - ALPN select callback function entry private data point - * - * @return none - */ -void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - const unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg), - void *arg); - - -/** - * @brief set the SSL context ALPN select protocol - * - * @param ctx - SSL context point - * @param protos - ALPN protocol name - * @param protos_len - ALPN protocol name bytes - * - * @return result - * 0 : OK - * 1 : failed - */ -int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, unsigned int protos_len); - -/** - * @brief set the SSL context next ALPN select callback function - * - * @param ctx - SSL context point - * @param cb - ALPN select callback function - * @param arg - ALPN select callback function entry private data point - * - * @return none - */ -void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg), - void *arg); - -/** - * @brief get SSL error code - * - * @param ssl - SSL point - * @param ret_code - SSL return code - * - * @return SSL error number - */ -int SSL_get_error(const SSL *ssl, int ret_code); - -/** - * @brief clear the SSL error code - * - * @param none - * - * @return none - */ -void ERR_clear_error(void); - -/** - * @brief get the current SSL error code - * - * @param none - * - * @return current SSL error number - */ -int ERR_get_error(void); - -/** - * @brief register the SSL error strings - * - * @param none - * - * @return none - */ -void ERR_load_SSL_strings(void); - -/** - * @brief initialize the SSL library - * - * @param none - * - * @return none - */ -void SSL_library_init(void); - -/** - * @brief generates a human-readable string representing the error code e - * and store it into the "ret" point memory - * - * @param e - error code - * @param ret - memory point to store the string - * - * @return the result string point - */ -char *ERR_error_string(unsigned long e, char *ret); - -/** - * @brief add the SSL context option - * - * @param ctx - SSL context point - * @param opt - new SSL context option - * - * @return the SSL context option - */ -unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt); - -/** - * @brief add the SSL context mode - * - * @param ctx - SSL context point - * @param mod - new SSL context mod - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_mode(SSL_CTX *ctx, int mod); - -/* -} -*/ - -/** - * @brief perform the SSL handshake - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - * -1 : a error catch - */ -int SSL_do_handshake(SSL *ssl); - -/** - * @brief get the SSL current version - * - * @param ssl - SSL point - * - * @return the version string - */ -const char *SSL_get_version(const SSL *ssl); - -/** - * @brief set the SSL context version - * - * @param ctx - SSL context point - * @param meth - SSL method point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); - -/** - * @brief get the bytes numbers which are to be read - * - * @param ssl - SSL point - * - * @return bytes number - */ -int SSL_pending(const SSL *ssl); - -/** - * @brief check if SSL want nothing - * - * @param ssl - SSL point - * - * @return result - * 0 : false - * 1 : true - */ -int SSL_want_nothing(const SSL *ssl); - -/** - * @brief check if SSL want to read - * - * @param ssl - SSL point - * - * @return result - * 0 : false - * 1 : true - */ -int SSL_want_read(const SSL *ssl); - -/** - * @brief check if SSL want to write - * - * @param ssl - SSL point - * - * @return result - * 0 : false - * 1 : true - */ -int SSL_want_write(const SSL *ssl); - -/** - * @brief get the SSL context current method - * - * @param ctx - SSL context point - * - * @return the SSL context current method - */ -const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); - -/** - * @brief get the SSL current method - * - * @param ssl - SSL point - * - * @return the SSL current method - */ -const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); - -/** - * @brief set the SSL method - * - * @param ssl - SSL point - * @param meth - SSL method point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); - -/** - * @brief add CA client certification into the SSL - * - * @param ssl - SSL point - * @param x - CA certification point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_add_client_CA(SSL *ssl, X509 *x); - -/** - * @brief add CA client certification into the SSL context - * - * @param ctx - SSL context point - * @param x - CA certification point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); - -/** - * @brief set the SSL CA certification list - * - * @param ssl - SSL point - * @param name_list - CA certification list - * - * @return none - */ -void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list); - -/** - * @brief set the SSL context CA certification list - * - * @param ctx - SSL context point - * @param name_list - CA certification list - * - * @return none - */ -void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); - -/** - * @briefget the SSL CA certification list - * - * @param ssl - SSL point - * - * @return CA certification list - */ -STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); - -/** - * @brief get the SSL context CA certification list - * - * @param ctx - SSL context point - * - * @return CA certification list - */ -STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); - -/** - * @brief get the SSL certification point - * - * @param ssl - SSL point - * - * @return SSL certification point - */ -X509 *SSL_get_certificate(const SSL *ssl); - -/** - * @brief get the SSL private key point - * - * @param ssl - SSL point - * - * @return SSL private key point - */ -EVP_PKEY *SSL_get_privatekey(const SSL *ssl); - -/** - * @brief set the SSL information callback function - * - * @param ssl - SSL point - * @param cb - information callback function - * - * @return none - */ -void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)); - -/** - * @brief get the SSL state - * - * @param ssl - SSL point - * - * @return SSL state - */ -OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); - -/** - * @brief set the SSL context read buffer length - * - * @param ctx - SSL context point - * @param len - read buffer length - * - * @return none - */ -void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); - -/** - * @brief set the SSL read buffer length - * - * @param ssl - SSL point - * @param len - read buffer length - * - * @return none - */ -void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); - -/** - * @brief set the SSL security level - * - * @param ssl - SSL point - * @param level - security level - * - * @return none - */ -void SSL_set_security_level(SSL *ssl, int level); - -/** - * @brief get the SSL security level - * - * @param ssl - SSL point - * - * @return security level - */ -int SSL_get_security_level(const SSL *ssl); - -/** - * @brief get the SSL verifying mode of the SSL context - * - * @param ctx - SSL context point - * - * @return verifying mode - */ -int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); - -/** - * @brief get the SSL verifying depth of the SSL context - * - * @param ctx - SSL context point - * - * @return verifying depth - */ -int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); - -/** - * @brief set the SSL context verifying of the SSL context - * - * @param ctx - SSL context point - * @param mode - verifying mode - * @param verify_callback - verifying callback function - * - * @return none - */ -void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); - -/** - * @brief set the SSL verifying of the SSL context - * - * @param ctx - SSL point - * @param mode - verifying mode - * @param verify_callback - verifying callback function - * - * @return none - */ -void SSL_set_verify(SSL *s, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); - -/** - * @brief set the SSL verify depth of the SSL context - * - * @param ctx - SSL context point - * @param depth - verifying depth - * - * @return none - */ -void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); - -/** - * @brief certification verifying callback function - * - * @param preverify_ok - verifying result - * @param x509_ctx - X509 certification point - * - * @return verifying result - */ -int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); - -/** - * @brief set the session timeout time - * - * @param ctx - SSL context point - * @param t - new session timeout time - * - * @return old session timeout time - */ -long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); - -/** - * @brief get the session timeout time - * - * @param ctx - SSL context point - * - * @return current session timeout time - */ -long SSL_CTX_get_timeout(const SSL_CTX *ctx); - -/** - * @brief set the SSL context cipher through the list string - * - * @param ctx - SSL context point - * @param str - cipher controller list string - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); - -/** - * @brief set the SSL cipher through the list string - * - * @param ssl - SSL point - * @param str - cipher controller list string - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_set_cipher_list(SSL *ssl, const char *str); - -/** - * @brief get the SSL cipher list string - * - * @param ssl - SSL point - * - * @return cipher controller list string - */ -const char *SSL_get_cipher_list(const SSL *ssl, int n); - -/** - * @brief get the SSL cipher - * - * @param ssl - SSL point - * - * @return current cipher - */ -const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); - -/** - * @brief get the SSL cipher string - * - * @param ssl - SSL point - * - * @return cipher string - */ -const char *SSL_get_cipher(const SSL *ssl); - -/** - * @brief get the SSL context object X509 certification storage - * - * @param ctx - SSL context point - * - * @return x509 certification storage - */ -X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); - -/** - * @brief set the SSL context object X509 certification store - * - * @param ctx - SSL context point - * @param store - X509 certification store - * - * @return none - */ -void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); - -/** - * @brief get the SSL specifical statement - * - * @param ssl - SSL point - * - * @return specifical statement - */ -int SSL_want(const SSL *ssl); - -/** - * @brief check if the SSL is SSL_X509_LOOKUP state - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_want_x509_lookup(const SSL *ssl); - -/** - * @brief reset the SSL - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_clear(SSL *ssl); - -/** - * @brief get the socket handle of the SSL - * - * @param ssl - SSL point - * - * @return result - * >= 0 : yes, and return socket handle - * < 0 : a error catch - */ -int SSL_get_fd(const SSL *ssl); - -/** - * @brief get the read only socket handle of the SSL - * - * @param ssl - SSL point - * - * @return result - * >= 0 : yes, and return socket handle - * < 0 : a error catch - */ -int SSL_get_rfd(const SSL *ssl); - -/** - * @brief get the write only socket handle of the SSL - * - * @param ssl - SSL point - * - * @return result - * >= 0 : yes, and return socket handle - * < 0 : a error catch - */ -int SSL_get_wfd(const SSL *ssl); - -/** - * @brief set the SSL if we can read as many as data - * - * @param ssl - SSL point - * @param yes - enable the function - * - * @return none - */ -void SSL_set_read_ahead(SSL *s, int yes); - -/** - * @brief set the SSL context if we can read as many as data - * - * @param ctx - SSL context point - * @param yes - enbale the function - * - * @return none - */ -void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); - -/** - * @brief get the SSL ahead signal if we can read as many as data - * - * @param ssl - SSL point - * - * @return SSL context ahead signal - */ -int SSL_get_read_ahead(const SSL *ssl); - -/** - * @brief get the SSL context ahead signal if we can read as many as data - * - * @param ctx - SSL context point - * - * @return SSL context ahead signal - */ -long SSL_CTX_get_read_ahead(SSL_CTX *ctx); - -/** - * @brief check if some data can be read - * - * @param ssl - SSL point - * - * @return - * 1 : there are bytes to be read - * 0 : no data - */ -int SSL_has_pending(const SSL *ssl); - -/** - * @brief load the X509 certification into SSL context - * - * @param ctx - SSL context point - * @param x - X509 certification point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);//loads the certificate x into ctx - -/** - * @brief load the ASN1 certification into SSL context - * - * @param ctx - SSL context point - * @param len - certification length - * @param d - data point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); - -/** - * @brief load the certification file into SSL context - * - * @param ctx - SSL context point - * @param file - certification file name - * @param type - certification encoding type - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); - -/** - * @brief load the certification chain file into SSL context - * - * @param ctx - SSL context point - * @param file - certification chain file name - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); - - -/** - * @brief load the ASN1 private key into SSL context - * - * @param ctx - SSL context point - * @param d - data point - * @param len - private key length - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len);//adds the private key of type pk stored at memory location d (length len) to ctx - -/** - * @brief load the private key file into SSL context - * - * @param ctx - SSL context point - * @param file - private key file name - * @param type - private key encoding type - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); - -/** - * @brief load the RSA private key into SSL context - * - * @param ctx - SSL context point - * @param x - RSA private key point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); - -/** - * @brief load the RSA ASN1 private key into SSL context - * - * @param ctx - SSL context point - * @param d - data point - * @param len - RSA private key length - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); - -/** - * @brief load the RSA private key file into SSL context - * - * @param ctx - SSL context point - * @param file - RSA private key file name - * @param type - private key encoding type - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); - - -/** - * @brief check if the private key and certification is matched - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_check_private_key(const SSL_CTX *ctx); - -/** - * @brief set the SSL context server information - * - * @param ctx - SSL context point - * @param serverinfo - server information string - * @param serverinfo_length - server information length - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, size_t serverinfo_length); - -/** - * @brief load the SSL context server infomation file into SSL context - * - * @param ctx - SSL context point - * @param file - server information file - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); - -/** - * @brief SSL select next function - * - * @param out - point of output data point - * @param outlen - output data length - * @param in - input data - * @param inlen - input data length - * @param client - client data point - * @param client_len -client data length - * - * @return NPN state - * OPENSSL_NPN_UNSUPPORTED : not support - * OPENSSL_NPN_NEGOTIATED : negotiated - * OPENSSL_NPN_NO_OVERLAP : no overlap - */ -int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, - const unsigned char *client, unsigned int client_len); - -/** - * @brief load the extra certification chain into the SSL context - * - * @param ctx - SSL context point - * @param x509 - X509 certification - * - * @return result - * 1 : OK - * 0 : failed - */ -long SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *); - -/** - * @brief control the SSL context - * - * @param ctx - SSL context point - * @param cmd - command - * @param larg - parameter length - * @param parg - parameter point - * - * @return result - * 1 : OK - * 0 : failed - */ -long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg); - -/** - * @brief get the SSL context cipher - * - * @param ctx - SSL context point - * - * @return SSL context cipher - */ -STACK *SSL_CTX_get_ciphers(const SSL_CTX *ctx); - -/** - * @brief check if the SSL context can read as many as data - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx); - -/** - * @brief get the SSL context extra data - * - * @param ctx - SSL context point - * @param idx - index - * - * @return data point - */ -char *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); - -/** - * @brief get the SSL context quiet shutdown option - * - * @param ctx - SSL context point - * - * @return quiet shutdown option - */ -int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); - -/** - * @brief load the SSL context CA file - * - * @param ctx - SSL context point - * @param CAfile - CA certification file - * @param CApath - CA certification file path - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); - -/** - * @brief add SSL context reference count by '1' - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_up_ref(SSL_CTX *ctx); - -/** - * @brief set SSL context application private data - * - * @param ctx - SSL context point - * @param arg - private data - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_app_data(SSL_CTX *ctx, void *arg); - -/** - * @brief set SSL context client certification callback function - * - * @param ctx - SSL context point - * @param cb - callback function - * - * @return none - */ -void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); - -/** - * @brief set the SSL context if we can read as many as data - * - * @param ctx - SSL context point - * @param m - enable the fuction - * - * @return none - */ -void SSL_CTX_set_default_read_ahead(SSL_CTX *ctx, int m); - -/** - * @brief set SSL context default verifying path - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); - -/** - * @brief set SSL context default verifying directory - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); - -/** - * @brief set SSL context default verifying file - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); - -/** - * @brief set SSL context extra data - * - * @param ctx - SSL context point - * @param idx - data index - * @param arg - data point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, char *arg); - -/** - * @brief clear the SSL context option bit of "op" - * - * @param ctx - SSL context point - * @param op - option - * - * @return SSL context option - */ -unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); - -/** - * @brief get the SSL context option - * - * @param ctx - SSL context point - * @param op - option - * - * @return SSL context option - */ -unsigned long SSL_CTX_get_options(SSL_CTX *ctx); - -/** - * @brief set the SSL context quiet shutdown mode - * - * @param ctx - SSL context point - * @param mode - mode - * - * @return none - */ -void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); - -/** - * @brief get the SSL context X509 certification - * - * @param ctx - SSL context point - * - * @return X509 certification - */ -X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); - -/** - * @brief get the SSL context private key - * - * @param ctx - SSL context point - * - * @return private key - */ -EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); - -/** - * @brief set SSL context PSK identity hint - * - * @param ctx - SSL context point - * @param hint - PSK identity hint - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint); - -/** - * @brief set SSL context PSK server callback function - * - * @param ctx - SSL context point - * @param callback - callback function - * - * @return none - */ -void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, - unsigned int (*callback)(SSL *ssl, - const char *identity, - unsigned char *psk, - int max_psk_len)); -/** - * @brief get alert description string - * - * @param value - alert value - * - * @return alert description string - */ -const char *SSL_alert_desc_string(int value); - -/** - * @brief get alert description long string - * - * @param value - alert value - * - * @return alert description long string - */ -const char *SSL_alert_desc_string_long(int value); - -/** - * @brief get alert type string - * - * @param value - alert value - * - * @return alert type string - */ -const char *SSL_alert_type_string(int value); - -/** - * @brief get alert type long string - * - * @param value - alert value - * - * @return alert type long string - */ -const char *SSL_alert_type_string_long(int value); - -/** - * @brief get SSL context of the SSL - * - * @param ssl - SSL point - * - * @return SSL context - */ -SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); - -/** - * @brief get SSL application data - * - * @param ssl - SSL point - * - * @return application data - */ -char *SSL_get_app_data(SSL *ssl); - -/** - * @brief get SSL cipher bits - * - * @param ssl - SSL point - * @param alg_bits - algorithm bits - * - * @return strength bits - */ -int SSL_get_cipher_bits(const SSL *ssl, int *alg_bits); - -/** - * @brief get SSL cipher name - * - * @param ssl - SSL point - * - * @return SSL cipher name - */ -char *SSL_get_cipher_name(const SSL *ssl); - -/** - * @brief get SSL cipher version - * - * @param ssl - SSL point - * - * @return SSL cipher version - */ -char *SSL_get_cipher_version(const SSL *ssl); - -/** - * @brief get SSL extra data - * - * @param ssl - SSL point - * @param idx - data index - * - * @return extra data - */ -char *SSL_get_ex_data(const SSL *ssl, int idx); - -/** - * @brief get index of the SSL extra data X509 storage context - * - * @param none - * - * @return data index - */ -int SSL_get_ex_data_X509_STORE_CTX_idx(void); - -/** - * @brief get peer certification chain - * - * @param ssl - SSL point - * - * @return certification chain - */ -STACK *SSL_get_peer_cert_chain(const SSL *ssl); - -/** - * @brief get peer certification - * - * @param ssl - SSL point - * - * @return certification - */ -X509 *SSL_get_peer_certificate(const SSL *ssl); - -/** - * @brief get SSL quiet shutdown mode - * - * @param ssl - SSL point - * - * @return quiet shutdown mode - */ -int SSL_get_quiet_shutdown(const SSL *ssl); - -/** - * @brief get SSL read only IO handle - * - * @param ssl - SSL point - * - * @return IO handle - */ -BIO *SSL_get_rbio(const SSL *ssl); - -/** - * @brief get SSL shared ciphers - * - * @param ssl - SSL point - * @param buf - buffer to store the ciphers - * @param len - buffer len - * - * @return shared ciphers - */ -char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); - -/** - * @brief get SSL shutdown mode - * - * @param ssl - SSL point - * - * @return shutdown mode - */ -int SSL_get_shutdown(const SSL *ssl); - -/** - * @brief get SSL session time - * - * @param ssl - SSL point - * - * @return session time - */ -long SSL_get_time(const SSL *ssl); - -/** - * @brief get SSL session timeout time - * - * @param ssl - SSL point - * - * @return session timeout time - */ -long SSL_get_timeout(const SSL *ssl); - -/** - * @brief get SSL verifying mode - * - * @param ssl - SSL point - * - * @return verifying mode - */ -int SSL_get_verify_mode(const SSL *ssl); - -/** - * @brief get SSL write only IO handle - * - * @param ssl - SSL point - * - * @return IO handle - */ -BIO *SSL_get_wbio(const SSL *ssl); - -/** - * @brief load SSL client CA certification file - * - * @param file - file name - * - * @return certification loading object - */ -STACK *SSL_load_client_CA_file(const char *file); - -/** - * @brief add SSL reference by '1' - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_up_ref(SSL *ssl); - -/** - * @brief read and put data into buf, but not clear the SSL low-level storage - * - * @param ssl - SSL point - * @param buf - storage buffer point - * @param num - data bytes - * - * @return result - * > 0 : OK, and return read bytes - * = 0 : connect is closed - * < 0 : a error catch - */ -int SSL_peek(SSL *ssl, void *buf, int num); - -/** - * @brief make SSL renegotiate - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_renegotiate(SSL *ssl); - -/** - * @brief get the state string where SSL is reading - * - * @param ssl - SSL point - * - * @return state string - */ -const char *SSL_rstate_string(SSL *ssl); - -/** - * @brief get the statement long string where SSL is reading - * - * @param ssl - SSL point - * - * @return statement long string - */ -const char *SSL_rstate_string_long(SSL *ssl); - -/** - * @brief set SSL accept statement - * - * @param ssl - SSL point - * - * @return none - */ -void SSL_set_accept_state(SSL *ssl); - -/** - * @brief set SSL application data - * - * @param ssl - SSL point - * @param arg - SSL application data point - * - * @return none - */ -void SSL_set_app_data(SSL *ssl, char *arg); - -/** - * @brief set SSL BIO - * - * @param ssl - SSL point - * @param rbio - read only IO - * @param wbio - write only IO - * - * @return none - */ -void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); - -/** - * @brief clear SSL option - * - * @param ssl - SSL point - * @param op - clear option - * - * @return SSL option - */ -unsigned long SSL_clear_options(SSL *ssl, unsigned long op); - -/** - * @brief get SSL option - * - * @param ssl - SSL point - * - * @return SSL option - */ -unsigned long SSL_get_options(SSL *ssl); - -/** - * @brief clear SSL option - * - * @param ssl - SSL point - * @param op - setting option - * - * @return SSL option - */ -unsigned long SSL_set_options(SSL *ssl, unsigned long op); - -/** - * @brief set SSL quiet shutdown mode - * - * @param ssl - SSL point - * @param mode - quiet shutdown mode - * - * @return none - */ -void SSL_set_quiet_shutdown(SSL *ssl, int mode); - -/** - * @brief set SSL shutdown mode - * - * @param ssl - SSL point - * @param mode - shutdown mode - * - * @return none - */ -void SSL_set_shutdown(SSL *ssl, int mode); - -/** - * @brief set SSL session time - * - * @param ssl - SSL point - * @param t - session time - * - * @return session time - */ -void SSL_set_time(SSL *ssl, long t); - -/** - * @brief set SSL session timeout time - * - * @param ssl - SSL point - * @param t - session timeout time - * - * @return session timeout time - */ -void SSL_set_timeout(SSL *ssl, long t); - -/** - * @brief get SSL statement string - * - * @param ssl - SSL point - * - * @return SSL statement string - */ -char *SSL_state_string(const SSL *ssl); - -/** - * @brief get SSL statement long string - * - * @param ssl - SSL point - * - * @return SSL statement long string - */ -char *SSL_state_string_long(const SSL *ssl); - -/** - * @brief get SSL renegotiation count - * - * @param ssl - SSL point - * - * @return renegotiation count - */ -long SSL_total_renegotiations(SSL *ssl); - -/** - * @brief get SSL version - * - * @param ssl - SSL point - * - * @return SSL version - */ -int SSL_version(const SSL *ssl); - -/** - * @brief set SSL PSK identity hint - * - * @param ssl - SSL point - * @param hint - identity hint - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_use_psk_identity_hint(SSL *ssl, const char *hint); - -/** - * @brief get SSL PSK identity hint - * - * @param ssl - SSL point - * - * @return identity hint - */ -const char *SSL_get_psk_identity_hint(SSL *ssl); - -/** - * @brief get SSL PSK identity - * - * @param ssl - SSL point - * - * @return identity - */ -const char *SSL_get_psk_identity(SSL *ssl); - -#ifdef __cplusplus -} -#endif - -#endif +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +#ifndef _SSL_H_ +#define _SSL_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "internal/ssl_x509.h" +#include "internal/ssl_pkey.h" + +/* +{ +*/ + +/** + * @brief create a SSL context + * + * @param method - the SSL context method point + * + * @return the context point + */ +SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); + +/** + * @brief free a SSL context + * + * @param method - the SSL context point + * + * @return none + */ +void SSL_CTX_free(SSL_CTX *ctx); + +/** + * @brief create a SSL + * + * @param ctx - the SSL context point + * + * @return the SSL point + */ +SSL* SSL_new(SSL_CTX *ctx); + +/** + * @brief free the SSL + * + * @param ssl - the SSL point + * + * @return none + */ +void SSL_free(SSL *ssl); + +/** + * @brief connect to the remote SSL server + * + * @param ssl - the SSL point + * + * @return result + * 1 : OK + * -1 : failed + */ +int SSL_connect(SSL *ssl); + +/** + * @brief accept the remote connection + * + * @param ssl - the SSL point + * + * @return result + * 1 : OK + * -1 : failed + */ +int SSL_accept(SSL *ssl); + +/** + * @brief read data from to remote + * + * @param ssl - the SSL point which has been connected + * @param buffer - the received data buffer point + * @param len - the received data length + * + * @return result + * > 0 : OK, and return received data bytes + * = 0 : connection is closed + * < 0 : an error catch + */ +int SSL_read(SSL *ssl, void *buffer, int len); + +/** + * @brief send the data to remote + * + * @param ssl - the SSL point which has been connected + * @param buffer - the send data buffer point + * @param len - the send data length + * + * @return result + * > 0 : OK, and return sent data bytes + * = 0 : connection is closed + * < 0 : an error catch + */ +int SSL_write(SSL *ssl, const void *buffer, int len); + +/** + * @brief get the verifying result of the SSL certification + * + * @param ssl - the SSL point + * + * @return the result of verifying + */ +long SSL_get_verify_result(const SSL *ssl); + +/** + * @brief shutdown the connection + * + * @param ssl - the SSL point + * + * @return result + * 1 : OK + * 0 : shutdown is not finished + * -1 : an error catch + */ +int SSL_shutdown(SSL *ssl); + +/** + * @brief bind the socket file description into the SSL + * + * @param ssl - the SSL point + * @param fd - socket handle + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_set_fd(SSL *ssl, int fd); + +/** + * @brief These functions load the private key into the SSL_CTX or SSL object + * + * @param ctx - the SSL context point + * @param pkey - private key object point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + +/** + * @brief These functions load the certification into the SSL_CTX or SSL object + * + * @param ctx - the SSL context point + * @param pkey - certification object point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the SSLV2.3 version SSL context client method + */ +const SSL_METHOD* SSLv23_client_method(void); + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the TLSV1.0 version SSL context client method + */ +const SSL_METHOD* TLSv1_client_method(void); + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the SSLV1.0 version SSL context client method + */ +const SSL_METHOD* SSLv3_client_method(void); + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the TLSV1.1 version SSL context client method + */ +const SSL_METHOD* TLSv1_1_client_method(void); + +/** + * @brief create the target SSL context client method + * + * @param none + * + * @return the TLSV1.2 version SSL context client method + */ +const SSL_METHOD* TLSv1_2_client_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLS any version SSL context client method + */ +const SSL_METHOD* TLS_client_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the SSLV2.3 version SSL context server method + */ +const SSL_METHOD* SSLv23_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLSV1.1 version SSL context server method + */ +const SSL_METHOD* TLSv1_1_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLSV1.2 version SSL context server method + */ +const SSL_METHOD* TLSv1_2_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLSV1.0 version SSL context server method + */ +const SSL_METHOD* TLSv1_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the SSLV3.0 version SSL context server method + */ +const SSL_METHOD* SSLv3_server_method(void); + +/** + * @brief create the target SSL context server method + * + * @param none + * + * @return the TLS any version SSL context server method + */ +const SSL_METHOD* TLS_server_method(void); + + +/** + * @brief set the SSL context ALPN select callback function + * + * @param ctx - SSL context point + * @param cb - ALPN select callback function + * @param arg - ALPN select callback function entry private data point + * + * @return none + */ +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), + void *arg); + + +/** + * @brief set the SSL context ALPN select protocol + * + * @param ctx - SSL context point + * @param protos - ALPN protocol name + * @param protos_len - ALPN protocol name bytes + * + * @return result + * 0 : OK + * 1 : failed + */ +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, unsigned int protos_len); + +/** + * @brief set the SSL context next ALPN select callback function + * + * @param ctx - SSL context point + * @param cb - ALPN select callback function + * @param arg - ALPN select callback function entry private data point + * + * @return none + */ +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), + void *arg); + +/** + * @brief get SSL error code + * + * @param ssl - SSL point + * @param ret_code - SSL return code + * + * @return SSL error number + */ +int SSL_get_error(const SSL *ssl, int ret_code); + +/** + * @brief clear the SSL error code + * + * @param none + * + * @return none + */ +void ERR_clear_error(void); + +/** + * @brief get the current SSL error code + * + * @param none + * + * @return current SSL error number + */ +int ERR_get_error(void); + +/** + * @brief register the SSL error strings + * + * @param none + * + * @return none + */ +void ERR_load_SSL_strings(void); + +/** + * @brief initialize the SSL library + * + * @param none + * + * @return none + */ +void SSL_library_init(void); + +/** + * @brief generates a human-readable string representing the error code e + * and store it into the "ret" point memory + * + * @param e - error code + * @param ret - memory point to store the string + * + * @return the result string point + */ +char *ERR_error_string(unsigned long e, char *ret); + +/** + * @brief add the SSL context option + * + * @param ctx - SSL context point + * @param opt - new SSL context option + * + * @return the SSL context option + */ +unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt); + +/** + * @brief add the SSL context mode + * + * @param ctx - SSL context point + * @param mod - new SSL context mod + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_mode(SSL_CTX *ctx, int mod); + +/* +} +*/ + +/** + * @brief perform the SSL handshake + * + * @param ssl - SSL point + * + * @return result + * 1 : OK + * 0 : failed + * -1 : a error catch + */ +int SSL_do_handshake(SSL *ssl); + +/** + * @brief get the SSL current version + * + * @param ssl - SSL point + * + * @return the version string + */ +const char *SSL_get_version(const SSL *ssl); + +/** + * @brief set the SSL context version + * + * @param ctx - SSL context point + * @param meth - SSL method point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +/** + * @brief get the bytes numbers which are to be read + * + * @param ssl - SSL point + * + * @return bytes number + */ +int SSL_pending(const SSL *ssl); + +/** + * @brief check if SSL want nothing + * + * @param ssl - SSL point + * + * @return result + * 0 : false + * 1 : true + */ +int SSL_want_nothing(const SSL *ssl); + +/** + * @brief check if SSL want to read + * + * @param ssl - SSL point + * + * @return result + * 0 : false + * 1 : true + */ +int SSL_want_read(const SSL *ssl); + +/** + * @brief check if SSL want to write + * + * @param ssl - SSL point + * + * @return result + * 0 : false + * 1 : true + */ +int SSL_want_write(const SSL *ssl); + +/** + * @brief get the SSL context current method + * + * @param ctx - SSL context point + * + * @return the SSL context current method + */ +const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); + +/** + * @brief get the SSL current method + * + * @param ssl - SSL point + * + * @return the SSL current method + */ +const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); + +/** + * @brief set the SSL method + * + * @param ssl - SSL point + * @param meth - SSL method point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); + +/** + * @brief add CA client certification into the SSL + * + * @param ssl - SSL point + * @param x - CA certification point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_add_client_CA(SSL *ssl, X509 *x); + +/** + * @brief add CA client certification into the SSL context + * + * @param ctx - SSL context point + * @param x - CA certification point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +/** + * @brief set the SSL CA certification list + * + * @param ssl - SSL point + * @param name_list - CA certification list + * + * @return none + */ +void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list); + +/** + * @brief set the SSL context CA certification list + * + * @param ctx - SSL context point + * @param name_list - CA certification list + * + * @return none + */ +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); + +/** + * @briefget the SSL CA certification list + * + * @param ssl - SSL point + * + * @return CA certification list + */ +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); + +/** + * @brief get the SSL context CA certification list + * + * @param ctx - SSL context point + * + * @return CA certification list + */ +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); + +/** + * @brief get the SSL certification point + * + * @param ssl - SSL point + * + * @return SSL certification point + */ +X509 *SSL_get_certificate(const SSL *ssl); + +/** + * @brief get the SSL private key point + * + * @param ssl - SSL point + * + * @return SSL private key point + */ +EVP_PKEY *SSL_get_privatekey(const SSL *ssl); + +/** + * @brief set the SSL information callback function + * + * @param ssl - SSL point + * @param cb - information callback function + * + * @return none + */ +void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)); + +/** + * @brief get the SSL state + * + * @param ssl - SSL point + * + * @return SSL state + */ +OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); + +/** + * @brief set the SSL context read buffer length + * + * @param ctx - SSL context point + * @param len - read buffer length + * + * @return none + */ +void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); + +/** + * @brief set the SSL read buffer length + * + * @param ssl - SSL point + * @param len - read buffer length + * + * @return none + */ +void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); + +/** + * @brief set the SSL security level + * + * @param ssl - SSL point + * @param level - security level + * + * @return none + */ +void SSL_set_security_level(SSL *ssl, int level); + +/** + * @brief get the SSL security level + * + * @param ssl - SSL point + * + * @return security level + */ +int SSL_get_security_level(const SSL *ssl); + +/** + * @brief get the SSL verifying mode of the SSL context + * + * @param ctx - SSL context point + * + * @return verifying mode + */ +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); + +/** + * @brief get the SSL verifying depth of the SSL context + * + * @param ctx - SSL context point + * + * @return verifying depth + */ +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); + +/** + * @brief set the SSL context verifying of the SSL context + * + * @param ctx - SSL context point + * @param mode - verifying mode + * @param verify_callback - verifying callback function + * + * @return none + */ +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); + +/** + * @brief set the SSL verifying of the SSL context + * + * @param ctx - SSL point + * @param mode - verifying mode + * @param verify_callback - verifying callback function + * + * @return none + */ +void SSL_set_verify(SSL *s, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); + +/** + * @brief set the SSL verify depth of the SSL context + * + * @param ctx - SSL context point + * @param depth - verifying depth + * + * @return none + */ +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); + +/** + * @brief certification verifying callback function + * + * @param preverify_ok - verifying result + * @param x509_ctx - X509 certification point + * + * @return verifying result + */ +int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); + +/** + * @brief set the session timeout time + * + * @param ctx - SSL context point + * @param t - new session timeout time + * + * @return old session timeout time + */ +long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); + +/** + * @brief get the session timeout time + * + * @param ctx - SSL context point + * + * @return current session timeout time + */ +long SSL_CTX_get_timeout(const SSL_CTX *ctx); + +/** + * @brief set the SSL context cipher through the list string + * + * @param ctx - SSL context point + * @param str - cipher controller list string + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); + +/** + * @brief set the SSL cipher through the list string + * + * @param ssl - SSL point + * @param str - cipher controller list string + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_set_cipher_list(SSL *ssl, const char *str); + +/** + * @brief get the SSL cipher list string + * + * @param ssl - SSL point + * + * @return cipher controller list string + */ +const char *SSL_get_cipher_list(const SSL *ssl, int n); + +/** + * @brief get the SSL cipher + * + * @param ssl - SSL point + * + * @return current cipher + */ +const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); + +/** + * @brief get the SSL cipher string + * + * @param ssl - SSL point + * + * @return cipher string + */ +const char *SSL_get_cipher(const SSL *ssl); + +/** + * @brief get the SSL context object X509 certification storage + * + * @param ctx - SSL context point + * + * @return x509 certification storage + */ +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); + +/** + * @brief set the SSL context object X509 certification store + * + * @param ctx - SSL context point + * @param store - X509 certification store + * + * @return none + */ +void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); + +/** + * @brief get the SSL specifical statement + * + * @param ssl - SSL point + * + * @return specifical statement + */ +int SSL_want(const SSL *ssl); + +/** + * @brief check if the SSL is SSL_X509_LOOKUP state + * + * @param ssl - SSL point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_want_x509_lookup(const SSL *ssl); + +/** + * @brief reset the SSL + * + * @param ssl - SSL point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_clear(SSL *ssl); + +/** + * @brief get the socket handle of the SSL + * + * @param ssl - SSL point + * + * @return result + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_fd(const SSL *ssl); + +/** + * @brief get the read only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return result + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_rfd(const SSL *ssl); + +/** + * @brief get the write only socket handle of the SSL + * + * @param ssl - SSL point + * + * @return result + * >= 0 : yes, and return socket handle + * < 0 : a error catch + */ +int SSL_get_wfd(const SSL *ssl); + +/** + * @brief set the SSL if we can read as many as data + * + * @param ssl - SSL point + * @param yes - enable the function + * + * @return none + */ +void SSL_set_read_ahead(SSL *s, int yes); + +/** + * @brief set the SSL context if we can read as many as data + * + * @param ctx - SSL context point + * @param yes - enbale the function + * + * @return none + */ +void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); + +/** + * @brief get the SSL ahead signal if we can read as many as data + * + * @param ssl - SSL point + * + * @return SSL context ahead signal + */ +int SSL_get_read_ahead(const SSL *ssl); + +/** + * @brief get the SSL context ahead signal if we can read as many as data + * + * @param ctx - SSL context point + * + * @return SSL context ahead signal + */ +long SSL_CTX_get_read_ahead(SSL_CTX *ctx); + +/** + * @brief check if some data can be read + * + * @param ssl - SSL point + * + * @return + * 1 : there are bytes to be read + * 0 : no data + */ +int SSL_has_pending(const SSL *ssl); + +/** + * @brief load the X509 certification into SSL context + * + * @param ctx - SSL context point + * @param x - X509 certification point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);//loads the certificate x into ctx + +/** + * @brief load the ASN1 certification into SSL context + * + * @param ctx - SSL context point + * @param len - certification length + * @param d - data point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); + +/** + * @brief load the certification file into SSL context + * + * @param ctx - SSL context point + * @param file - certification file name + * @param type - certification encoding type + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); + +/** + * @brief load the certification chain file into SSL context + * + * @param ctx - SSL context point + * @param file - certification chain file name + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); + + +/** + * @brief load the ASN1 private key into SSL context + * + * @param ctx - SSL context point + * @param d - data point + * @param len - private key length + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len);//adds the private key of type pk stored at memory location d (length len) to ctx + +/** + * @brief load the private key file into SSL context + * + * @param ctx - SSL context point + * @param file - private key file name + * @param type - private key encoding type + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); + +/** + * @brief load the RSA private key into SSL context + * + * @param ctx - SSL context point + * @param x - RSA private key point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); + +/** + * @brief load the RSA ASN1 private key into SSL context + * + * @param ctx - SSL context point + * @param d - data point + * @param len - RSA private key length + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); + +/** + * @brief load the RSA private key file into SSL context + * + * @param ctx - SSL context point + * @param file - RSA private key file name + * @param type - private key encoding type + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); + + +/** + * @brief check if the private key and certification is matched + * + * @param ctx - SSL context point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_check_private_key(const SSL_CTX *ctx); + +/** + * @brief set the SSL context server information + * + * @param ctx - SSL context point + * @param serverinfo - server information string + * @param serverinfo_length - server information length + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, size_t serverinfo_length); + +/** + * @brief load the SSL context server infomation file into SSL context + * + * @param ctx - SSL context point + * @param file - server information file + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); + +/** + * @brief SSL select next function + * + * @param out - point of output data point + * @param outlen - output data length + * @param in - input data + * @param inlen - input data length + * @param client - client data point + * @param client_len -client data length + * + * @return NPN state + * OPENSSL_NPN_UNSUPPORTED : not support + * OPENSSL_NPN_NEGOTIATED : negotiated + * OPENSSL_NPN_NO_OVERLAP : no overlap + */ +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const unsigned char *client, unsigned int client_len); + +/** + * @brief load the extra certification chain into the SSL context + * + * @param ctx - SSL context point + * @param x509 - X509 certification + * + * @return result + * 1 : OK + * 0 : failed + */ +long SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *); + +/** + * @brief control the SSL context + * + * @param ctx - SSL context point + * @param cmd - command + * @param larg - parameter length + * @param parg - parameter point + * + * @return result + * 1 : OK + * 0 : failed + */ +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg); + +/** + * @brief get the SSL context cipher + * + * @param ctx - SSL context point + * + * @return SSL context cipher + */ +STACK *SSL_CTX_get_ciphers(const SSL_CTX *ctx); + +/** + * @brief check if the SSL context can read as many as data + * + * @param ctx - SSL context point + * + * @return result + * 1 : OK + * 0 : failed + */ +long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx); + +/** + * @brief get the SSL context extra data + * + * @param ctx - SSL context point + * @param idx - index + * + * @return data point + */ +char *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); + +/** + * @brief get the SSL context quiet shutdown option + * + * @param ctx - SSL context point + * + * @return quiet shutdown option + */ +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); + +/** + * @brief load the SSL context CA file + * + * @param ctx - SSL context point + * @param CAfile - CA certification file + * @param CApath - CA certification file path + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); + +/** + * @brief add SSL context reference count by '1' + * + * @param ctx - SSL context point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_up_ref(SSL_CTX *ctx); + +/** + * @brief set SSL context application private data + * + * @param ctx - SSL context point + * @param arg - private data + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_app_data(SSL_CTX *ctx, void *arg); + +/** + * @brief set SSL context client certification callback function + * + * @param ctx - SSL context point + * @param cb - callback function + * + * @return none + */ +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); + +/** + * @brief set the SSL context if we can read as many as data + * + * @param ctx - SSL context point + * @param m - enable the fuction + * + * @return none + */ +void SSL_CTX_set_default_read_ahead(SSL_CTX *ctx, int m); + +/** + * @brief set SSL context default verifying path + * + * @param ctx - SSL context point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); + +/** + * @brief set SSL context default verifying directory + * + * @param ctx - SSL context point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); + +/** + * @brief set SSL context default verifying file + * + * @param ctx - SSL context point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); + +/** + * @brief set SSL context extra data + * + * @param ctx - SSL context point + * @param idx - data index + * @param arg - data point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, char *arg); + +/** + * @brief clear the SSL context option bit of "op" + * + * @param ctx - SSL context point + * @param op - option + * + * @return SSL context option + */ +unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); + +/** + * @brief get the SSL context option + * + * @param ctx - SSL context point + * @param op - option + * + * @return SSL context option + */ +unsigned long SSL_CTX_get_options(SSL_CTX *ctx); + +/** + * @brief set the SSL context quiet shutdown mode + * + * @param ctx - SSL context point + * @param mode - mode + * + * @return none + */ +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); + +/** + * @brief get the SSL context X509 certification + * + * @param ctx - SSL context point + * + * @return X509 certification + */ +X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); + +/** + * @brief get the SSL context private key + * + * @param ctx - SSL context point + * + * @return private key + */ +EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +/** + * @brief set SSL context PSK identity hint + * + * @param ctx - SSL context point + * @param hint - PSK identity hint + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint); + +/** + * @brief set SSL context PSK server callback function + * + * @param ctx - SSL context point + * @param callback - callback function + * + * @return none + */ +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*callback)(SSL *ssl, + const char *identity, + unsigned char *psk, + int max_psk_len)); +/** + * @brief get alert description string + * + * @param value - alert value + * + * @return alert description string + */ +const char *SSL_alert_desc_string(int value); + +/** + * @brief get alert description long string + * + * @param value - alert value + * + * @return alert description long string + */ +const char *SSL_alert_desc_string_long(int value); + +/** + * @brief get alert type string + * + * @param value - alert value + * + * @return alert type string + */ +const char *SSL_alert_type_string(int value); + +/** + * @brief get alert type long string + * + * @param value - alert value + * + * @return alert type long string + */ +const char *SSL_alert_type_string_long(int value); + +/** + * @brief get SSL context of the SSL + * + * @param ssl - SSL point + * + * @return SSL context + */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); + +/** + * @brief get SSL application data + * + * @param ssl - SSL point + * + * @return application data + */ +char *SSL_get_app_data(SSL *ssl); + +/** + * @brief get SSL cipher bits + * + * @param ssl - SSL point + * @param alg_bits - algorithm bits + * + * @return strength bits + */ +int SSL_get_cipher_bits(const SSL *ssl, int *alg_bits); + +/** + * @brief get SSL cipher name + * + * @param ssl - SSL point + * + * @return SSL cipher name + */ +char *SSL_get_cipher_name(const SSL *ssl); + +/** + * @brief get SSL cipher version + * + * @param ssl - SSL point + * + * @return SSL cipher version + */ +char *SSL_get_cipher_version(const SSL *ssl); + +/** + * @brief get SSL extra data + * + * @param ssl - SSL point + * @param idx - data index + * + * @return extra data + */ +char *SSL_get_ex_data(const SSL *ssl, int idx); + +/** + * @brief get index of the SSL extra data X509 storage context + * + * @param none + * + * @return data index + */ +int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +/** + * @brief get peer certification chain + * + * @param ssl - SSL point + * + * @return certification chain + */ +STACK *SSL_get_peer_cert_chain(const SSL *ssl); + +/** + * @brief get peer certification + * + * @param ssl - SSL point + * + * @return certification + */ +X509 *SSL_get_peer_certificate(const SSL *ssl); + +/** + * @brief get SSL quiet shutdown mode + * + * @param ssl - SSL point + * + * @return quiet shutdown mode + */ +int SSL_get_quiet_shutdown(const SSL *ssl); + +/** + * @brief get SSL read only IO handle + * + * @param ssl - SSL point + * + * @return IO handle + */ +BIO *SSL_get_rbio(const SSL *ssl); + +/** + * @brief get SSL shared ciphers + * + * @param ssl - SSL point + * @param buf - buffer to store the ciphers + * @param len - buffer len + * + * @return shared ciphers + */ +char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); + +/** + * @brief get SSL shutdown mode + * + * @param ssl - SSL point + * + * @return shutdown mode + */ +int SSL_get_shutdown(const SSL *ssl); + +/** + * @brief get SSL session time + * + * @param ssl - SSL point + * + * @return session time + */ +long SSL_get_time(const SSL *ssl); + +/** + * @brief get SSL session timeout time + * + * @param ssl - SSL point + * + * @return session timeout time + */ +long SSL_get_timeout(const SSL *ssl); + +/** + * @brief get SSL verifying mode + * + * @param ssl - SSL point + * + * @return verifying mode + */ +int SSL_get_verify_mode(const SSL *ssl); + +/** + * @brief get SSL write only IO handle + * + * @param ssl - SSL point + * + * @return IO handle + */ +BIO *SSL_get_wbio(const SSL *ssl); + +/** + * @brief load SSL client CA certification file + * + * @param file - file name + * + * @return certification loading object + */ +STACK *SSL_load_client_CA_file(const char *file); + +/** + * @brief add SSL reference by '1' + * + * @param ssl - SSL point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_up_ref(SSL *ssl); + +/** + * @brief read and put data into buf, but not clear the SSL low-level storage + * + * @param ssl - SSL point + * @param buf - storage buffer point + * @param num - data bytes + * + * @return result + * > 0 : OK, and return read bytes + * = 0 : connect is closed + * < 0 : a error catch + */ +int SSL_peek(SSL *ssl, void *buf, int num); + +/** + * @brief make SSL renegotiate + * + * @param ssl - SSL point + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_renegotiate(SSL *ssl); + +/** + * @brief get the state string where SSL is reading + * + * @param ssl - SSL point + * + * @return state string + */ +const char *SSL_rstate_string(SSL *ssl); + +/** + * @brief get the statement long string where SSL is reading + * + * @param ssl - SSL point + * + * @return statement long string + */ +const char *SSL_rstate_string_long(SSL *ssl); + +/** + * @brief set SSL accept statement + * + * @param ssl - SSL point + * + * @return none + */ +void SSL_set_accept_state(SSL *ssl); + +/** + * @brief set SSL application data + * + * @param ssl - SSL point + * @param arg - SSL application data point + * + * @return none + */ +void SSL_set_app_data(SSL *ssl, char *arg); + +/** + * @brief set SSL BIO + * + * @param ssl - SSL point + * @param rbio - read only IO + * @param wbio - write only IO + * + * @return none + */ +void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); + +/** + * @brief clear SSL option + * + * @param ssl - SSL point + * @param op - clear option + * + * @return SSL option + */ +unsigned long SSL_clear_options(SSL *ssl, unsigned long op); + +/** + * @brief get SSL option + * + * @param ssl - SSL point + * + * @return SSL option + */ +unsigned long SSL_get_options(SSL *ssl); + +/** + * @brief clear SSL option + * + * @param ssl - SSL point + * @param op - setting option + * + * @return SSL option + */ +unsigned long SSL_set_options(SSL *ssl, unsigned long op); + +/** + * @brief set SSL quiet shutdown mode + * + * @param ssl - SSL point + * @param mode - quiet shutdown mode + * + * @return none + */ +void SSL_set_quiet_shutdown(SSL *ssl, int mode); + +/** + * @brief set SSL shutdown mode + * + * @param ssl - SSL point + * @param mode - shutdown mode + * + * @return none + */ +void SSL_set_shutdown(SSL *ssl, int mode); + +/** + * @brief set SSL session time + * + * @param ssl - SSL point + * @param t - session time + * + * @return session time + */ +void SSL_set_time(SSL *ssl, long t); + +/** + * @brief set SSL session timeout time + * + * @param ssl - SSL point + * @param t - session timeout time + * + * @return session timeout time + */ +void SSL_set_timeout(SSL *ssl, long t); + +/** + * @brief get SSL statement string + * + * @param ssl - SSL point + * + * @return SSL statement string + */ +char *SSL_state_string(const SSL *ssl); + +/** + * @brief get SSL statement long string + * + * @param ssl - SSL point + * + * @return SSL statement long string + */ +char *SSL_state_string_long(const SSL *ssl); + +/** + * @brief get SSL renegotiation count + * + * @param ssl - SSL point + * + * @return renegotiation count + */ +long SSL_total_renegotiations(SSL *ssl); + +/** + * @brief get SSL version + * + * @param ssl - SSL point + * + * @return SSL version + */ +int SSL_version(const SSL *ssl); + +/** + * @brief set SSL PSK identity hint + * + * @param ssl - SSL point + * @param hint - identity hint + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_use_psk_identity_hint(SSL *ssl, const char *hint); + +/** + * @brief get SSL PSK identity hint + * + * @param ssl - SSL point + * + * @return identity hint + */ +const char *SSL_get_psk_identity_hint(SSL *ssl); + +/** + * @brief get SSL PSK identity + * + * @param ssl - SSL point + * + * @return identity + */ +const char *SSL_get_psk_identity(SSL *ssl); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/openssl/platform/ssl_pm.h b/include/openssl/platform/ssl_pm.h old mode 100755 new mode 100644 diff --git a/include/openssl/platform/ssl_port.h b/include/openssl/platform/ssl_port.h old mode 100755 new mode 100644 diff --git a/lib/libcrypto.a b/lib/libcrypto.a old mode 100755 new mode 100644 diff --git a/lib/libespconn.a b/lib/libespconn.a old mode 100755 new mode 100644 diff --git a/lib/libespnow.a b/lib/libespnow.a old mode 100755 new mode 100644 diff --git a/lib/libfreertos.a b/lib/libfreertos.a old mode 100755 new mode 100644 diff --git a/lib/libmain.a b/lib/libmain.a old mode 100755 new mode 100644 diff --git a/lib/libmesh.a b/lib/libmesh.a old mode 100755 new mode 100644 diff --git a/lib/libminic.a b/lib/libminic.a old mode 100755 new mode 100644 diff --git a/lib/libnet80211.a b/lib/libnet80211.a old mode 100755 new mode 100644 diff --git a/lib/libnopoll.a b/lib/libnopoll.a old mode 100755 new mode 100644 diff --git a/lib/libpp.a b/lib/libpp.a old mode 100755 new mode 100644 diff --git a/lib/libpwm.a b/lib/libpwm.a old mode 100755 new mode 100644 diff --git a/lib/libsmartconfig.a b/lib/libsmartconfig.a old mode 100755 new mode 100644 diff --git a/lib/libssl.a b/lib/libssl.a old mode 100755 new mode 100644 diff --git a/lib/libwpa.a b/lib/libwpa.a old mode 100755 new mode 100644 diff --git a/lib/libwps.a b/lib/libwps.a old mode 100755 new mode 100644 diff --git a/third_party/Makefile b/third_party/Makefile index bc9a4769..f6700bca 100644 --- a/third_party/Makefile +++ b/third_party/Makefile @@ -1,120 +1,120 @@ -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of object file images to be generated () -# GEN_BINS - list of binaries to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -TARGET = eagle -#FLAVOR = release -FLAVOR = debug - -#EXTRA_CCFLAGS += -u - -ifndef PDIR # { -GEN_IMAGES= eagle.app.v6.out -GEN_BINS= eagle.app.v6.bin -SPECIAL_MKTARGETS=$(APP_MKTARGETS) -SUBDIRS= \ - user - -endif # } PDIR - -LDDIR = $(SDK_PATH)/ld - -CCFLAGS += -Os - -TARGET_LDFLAGS = \ - -nostdlib \ - -Wl,-EL \ - --longcalls \ - --text-section-literals - -ifeq ($(FLAVOR),debug) - TARGET_LDFLAGS += -g -O2 -endif - -ifeq ($(FLAVOR),release) - TARGET_LDFLAGS += -g -O0 -endif - -COMPONENTS_eagle.app.v6 = \ - user/libuser.a \ - spiffs/libspiffs.a \ - driver/libdriver.a - -LINKFLAGS_eagle.app.v6 = \ - -L$(SDK_PATH)/lib \ - -Wl,--gc-sections \ - -nostdlib \ - -T$(LD_FILE) \ - -Wl,--no-check-sections \ - -u call_user_start \ - -Wl,-static \ - -Wl,--start-group \ - -lcirom \ - -lgcc \ - -lhal \ - -lphy \ - -lpp \ - -lnet80211 \ - -lwpa \ - -lmain \ - -lfreertos \ - -llwip \ - $(DEP_LIBS_eagle.app.v6) \ - -Wl,--end-group - -DEPENDS_eagle.app.v6 = \ - $(LD_FILE) \ - $(LDDIR)/eagle.rom.addr.v6.ld - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# - -#UNIVERSAL_TARGET_DEFINES = \ - -# Other potential configuration flags include: -# -DTXRX_TXBUF_DEBUG -# -DTXRX_RXBUF_DEBUG -# -DWLAN_CONFIG_CCX -CONFIGURATION_DEFINES = -DMEMLEAK_DEBUG - -DEFINES += \ - $(UNIVERSAL_TARGET_DEFINES) \ - $(CONFIGURATION_DEFINES) - -DDEFINES += \ - $(UNIVERSAL_TARGET_DEFINES) \ - $(CONFIGURATION_DEFINES) - - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -sinclude $(SDK_PATH)/Makefile - -.PHONY: FORCE -FORCE: - +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of object file images to be generated () +# GEN_BINS - list of binaries to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +TARGET = eagle +#FLAVOR = release +FLAVOR = debug + +#EXTRA_CCFLAGS += -u + +ifndef PDIR # { +GEN_IMAGES= eagle.app.v6.out +GEN_BINS= eagle.app.v6.bin +SPECIAL_MKTARGETS=$(APP_MKTARGETS) +SUBDIRS= \ + user + +endif # } PDIR + +LDDIR = $(SDK_PATH)/ld + +CCFLAGS += -Os + +TARGET_LDFLAGS = \ + -nostdlib \ + -Wl,-EL \ + --longcalls \ + --text-section-literals + +ifeq ($(FLAVOR),debug) + TARGET_LDFLAGS += -g -O2 +endif + +ifeq ($(FLAVOR),release) + TARGET_LDFLAGS += -g -O0 +endif + +COMPONENTS_eagle.app.v6 = \ + user/libuser.a \ + spiffs/libspiffs.a \ + driver/libdriver.a + +LINKFLAGS_eagle.app.v6 = \ + -L$(SDK_PATH)/lib \ + -Wl,--gc-sections \ + -nostdlib \ + -T$(LD_FILE) \ + -Wl,--no-check-sections \ + -u call_user_start \ + -Wl,-static \ + -Wl,--start-group \ + -lcirom \ + -lgcc \ + -lhal \ + -lphy \ + -lpp \ + -lnet80211 \ + -lwpa \ + -lmain \ + -lfreertos \ + -llwip \ + $(DEP_LIBS_eagle.app.v6) \ + -Wl,--end-group + +DEPENDS_eagle.app.v6 = \ + $(LD_FILE) \ + $(LDDIR)/eagle.rom.addr.v6.ld + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# + +#UNIVERSAL_TARGET_DEFINES = \ + +# Other potential configuration flags include: +# -DTXRX_TXBUF_DEBUG +# -DTXRX_RXBUF_DEBUG +# -DWLAN_CONFIG_CCX +CONFIGURATION_DEFINES = -DMEMLEAK_DEBUG + +DEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + +DDEFINES += \ + $(UNIVERSAL_TARGET_DEFINES) \ + $(CONFIGURATION_DEFINES) + + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +sinclude $(SDK_PATH)/Makefile + +.PHONY: FORCE +FORCE: + diff --git a/third_party/freertos/Makefile b/third_party/freertos/Makefile index 87cd29f3..ce7d3cf3 100644 --- a/third_party/freertos/Makefile +++ b/third_party/freertos/Makefile @@ -1,50 +1,50 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -GEN_LIBS = libfreertos.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -# MEMLEAK_DEBUG must be defined for FreeRTOS. -DEFINES += -DMEMLEAK_DEBUG -DICACHE_FLASH - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -INCLUDES += -I ../../rom/include -INCLUDES += -I ../../include/ets -INCLUDES += -I ./include -I $(PDIR)include/freertos -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = libfreertos.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +# MEMLEAK_DEBUG must be defined for FreeRTOS. +DEFINES += -DMEMLEAK_DEBUG -DICACHE_FLASH + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +INCLUDES += -I ../../rom/include +INCLUDES += -I ../../include/ets +INCLUDES += -I ./include -I $(PDIR)include/freertos +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/third_party/freertos/croutine.c b/third_party/freertos/croutine.c index 84bdacfe..1d4499c5 100644 --- a/third_party/freertos/croutine.c +++ b/third_party/freertos/croutine.c @@ -1,393 +1,393 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/croutine.h" - -/* - * Some kernel aware debuggers require data to be viewed to be global, rather - * than file scope. - */ -#ifdef portREMOVE_STATIC_QUALIFIER - #define static -#endif - - -/* Lists for ready and blocked co-routines. --------------------*/ -static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ -static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */ -static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ -static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ -static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ -static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ - -/* Other file private variables. --------------------------------*/ -corCRCB * pxCurrentCoRoutine = NULL; -static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0; -static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; - -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - -/* The initial state of the co-routine when it is created. */ -#define corINITIAL_STATE ( 0 ) - -/* - * Place the co-routine represented by pxCRCB into the appropriate ready queue - * for the priority. It is inserted at the end of the list. - * - * This macro accesses the co-routine ready lists and therefore must not be - * used from within an ISR. - */ -#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ -{ \ - if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ - { \ - uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ - } \ - vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ -} - -/* - * Utility to ready all the lists used by the scheduler. This is called - * automatically upon the creation of the first co-routine. - */ -static void prvInitialiseCoRoutineLists( void ); - -/* - * Co-routines that are readied by an interrupt cannot be placed directly into - * the ready lists (there is no mutual exclusion). Instead they are placed in - * in the pending ready list in order that they can later be moved to the ready - * list by the co-routine scheduler. - */ -static void prvCheckPendingReadyList( void ); - -/* - * Macro that looks at the list of co-routines that are currently delayed to - * see if any require waking. - * - * Co-routines are stored in the queue in the order of their wake time - - * meaning once one co-routine has been found whose timer has not expired - * we need not look any further down the list. - */ -static void prvCheckDelayedList( void ); - -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ) -{ -signed portBASE_TYPE xReturn; -corCRCB *pxCoRoutine; - - /* Allocate the memory that will store the co-routine control block. */ - pxCoRoutine = ( corCRCB * ) os_malloc( sizeof( corCRCB ) ); - if( pxCoRoutine ) - { - /* If pxCurrentCoRoutine is NULL then this is the first co-routine to - be created and the co-routine data structures need initialising. */ - if( pxCurrentCoRoutine == NULL ) - { - pxCurrentCoRoutine = pxCoRoutine; - prvInitialiseCoRoutineLists(); - } - - /* Check the priority is within limits. */ - if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) - { - uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; - } - - /* Fill out the co-routine control block from the function parameters. */ - pxCoRoutine->uxState = corINITIAL_STATE; - pxCoRoutine->uxPriority = uxPriority; - pxCoRoutine->uxIndex = uxIndex; - pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; - - /* Initialise all the other co-routine control block parameters. */ - vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); - vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); - - /* Set the co-routine control block as a link back from the xListItem. - This is so we can get back to the containing CRCB from a generic item - in a list. */ - listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); - listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); - - /* Event lists are always in priority order. */ - listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); - - /* Now the co-routine has been initialised it can be added to the ready - list at the correct priority. */ - prvAddCoRoutineToReadyQueue( pxCoRoutine ); - - xReturn = pdPASS; - } - else - { - xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ) -{ -portTickType xTimeToWake; - - /* Calculate the time to wake - this may overflow but this is - not a problem. */ - xTimeToWake = xCoRoutineTickCount + xTicksToDelay; - - /* We must remove ourselves from the ready list before adding - ourselves to the blocked list as the same list item is used for - both lists. */ - ( void ) uxListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); - - /* The list item will be inserted in wake time order. */ - listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); - - if( xTimeToWake < xCoRoutineTickCount ) - { - /* Wake time has overflowed. Place this item in the - overflow list. */ - vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); - } - else - { - /* The wake time has not overflowed, so we can use the - current block list. */ - vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); - } - - if( pxEventList ) - { - /* Also add the co-routine to an event list. If this is done then the - function must be called with interrupts disabled. */ - vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); - } -} -/*-----------------------------------------------------------*/ - -static void prvCheckPendingReadyList( void ) -{ - /* Are there any co-routines waiting to get moved to the ready list? These - are co-routines that have been readied by an ISR. The ISR cannot access - the ready lists itself. */ - while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) - { - corCRCB *pxUnblockedCRCB; - - /* The pending ready list can be accessed by an ISR. */ - //portDISABLE_INTERRUPTS(); -PortDisableInt_NoNest(); - { - pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); - ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); - } -// portENABLE_INTERRUPTS(); -PortEnableInt_NoNest(); - - ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); - prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); - } -} -/*-----------------------------------------------------------*/ - -static void prvCheckDelayedList( void ) -{ -corCRCB *pxCRCB; - - xPassedTicks = xTaskGetTickCount() - xLastTickCount; - while( xPassedTicks ) - { - xCoRoutineTickCount++; - xPassedTicks--; - - /* If the tick count has overflowed we need to swap the ready lists. */ - if( xCoRoutineTickCount == 0 ) - { - xList * pxTemp; - - /* Tick count has overflowed so we need to swap the delay lists. If there are - any items in pxDelayedCoRoutineList here then there is an error! */ - pxTemp = pxDelayedCoRoutineList; - pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; - pxOverflowDelayedCoRoutineList = pxTemp; - } - - /* See if this tick has made a timeout expire. */ - while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) - { - pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); - - if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) - { - /* Timeout not yet expired. */ - break; - } - - //portDISABLE_INTERRUPTS(); -PortDisableInt_NoNest(); - { - /* The event could have occurred just before this critical - section. If this is the case then the generic list item will - have been moved to the pending ready list and the following - line is still valid. Also the pvContainer parameter will have - been set to NULL so the following lines are also valid. */ - uxListRemove( &( pxCRCB->xGenericListItem ) ); - - /* Is the co-routine waiting on an event also? */ - if( pxCRCB->xEventListItem.pvContainer ) - { - ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); - } - } -// portENABLE_INTERRUPTS(); -PortEnableInt_NoNest(); - - prvAddCoRoutineToReadyQueue( pxCRCB ); - } - } - - xLastTickCount = xCoRoutineTickCount; -} -/*-----------------------------------------------------------*/ - -void vCoRoutineSchedule( void ) -{ - /* See if any co-routines readied by events need moving to the ready lists. */ - prvCheckPendingReadyList(); - - /* See if any delayed co-routines have timed out. */ - prvCheckDelayedList(); - - /* Find the highest priority queue that contains ready co-routines. */ - while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) - { - if( uxTopCoRoutineReadyPriority == 0 ) - { - /* No more co-routines to check. */ - return; - } - --uxTopCoRoutineReadyPriority; - } - - /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines - of the same priority get an equal share of the processor time. */ - listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); - - /* Call the co-routine. */ - ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); - - return; -} -/*-----------------------------------------------------------*/ - -static void prvInitialiseCoRoutineLists( void ) -{ -unsigned portBASE_TYPE uxPriority; - - for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) - { - vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); - } - - vListInitialise( ( xList * ) &xDelayedCoRoutineList1 ); - vListInitialise( ( xList * ) &xDelayedCoRoutineList2 ); - vListInitialise( ( xList * ) &xPendingReadyCoRoutineList ); - - /* Start with pxDelayedCoRoutineList using list1 and the - pxOverflowDelayedCoRoutineList using list2. */ - pxDelayedCoRoutineList = &xDelayedCoRoutineList1; - pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; -} -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ) -{ -corCRCB *pxUnblockedCRCB; -signed portBASE_TYPE xReturn; - - /* This function is called from within an interrupt. It can only access - event lists and the pending ready list. This function assumes that a - check has already been made to ensure pxEventList is not empty. */ - pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); - ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); - vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); - - if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) - { - xReturn = pdTRUE; - } - else - { - xReturn = pdFALSE; - } - - return xReturn; -} - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/croutine.h" + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + + +/* Lists for ready and blocked co-routines. --------------------*/ +static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ +static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */ +static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ +static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ +static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ +static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ + +/* Other file private variables. --------------------------------*/ +corCRCB * pxCurrentCoRoutine = NULL; +static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0; +static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; +#endif + +/* The initial state of the co-routine when it is created. */ +#define corINITIAL_STATE ( 0 ) + +/* + * Place the co-routine represented by pxCRCB into the appropriate ready queue + * for the priority. It is inserted at the end of the list. + * + * This macro accesses the co-routine ready lists and therefore must not be + * used from within an ISR. + */ +#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ +{ \ + if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ + { \ + uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ + } \ + vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ +} + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first co-routine. + */ +static void prvInitialiseCoRoutineLists( void ); + +/* + * Co-routines that are readied by an interrupt cannot be placed directly into + * the ready lists (there is no mutual exclusion). Instead they are placed in + * in the pending ready list in order that they can later be moved to the ready + * list by the co-routine scheduler. + */ +static void prvCheckPendingReadyList( void ); + +/* + * Macro that looks at the list of co-routines that are currently delayed to + * see if any require waking. + * + * Co-routines are stored in the queue in the order of their wake time - + * meaning once one co-routine has been found whose timer has not expired + * we need not look any further down the list. + */ +static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ) +{ +signed portBASE_TYPE xReturn; +corCRCB *pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( corCRCB * ) os_malloc( sizeof( corCRCB ) ); + if( pxCoRoutine ) + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + { + pxCurrentCoRoutine = pxCoRoutine; + prvInitialiseCoRoutineLists(); + } + + /* Check the priority is within limits. */ + if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + pxCoRoutine->uxPriority = uxPriority; + pxCoRoutine->uxIndex = uxIndex; + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + + /* Set the co-routine control block as a link back from the xListItem. + This is so we can get back to the containing CRCB from a generic item + in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority ); + + /* Now the co-routine has been initialised it can be added to the ready + list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList ) +{ +portTickType xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + ( void ) uxListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xCoRoutineTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckPendingReadyList( void ) +{ + /* Are there any co-routines waiting to get moved to the ready list? These + are co-routines that have been readied by an ISR. The ISR cannot access + the ready lists itself. */ + while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) + { + corCRCB *pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + //portDISABLE_INTERRUPTS(); +PortDisableInt_NoNest(); + { + pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } +// portENABLE_INTERRUPTS(); +PortEnableInt_NoNest(); + + ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckDelayedList( void ) +{ +corCRCB *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + while( xPassedTicks ) + { + xCoRoutineTickCount++; + xPassedTicks--; + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + { + xList * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) + { + pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); + + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + { + /* Timeout not yet expired. */ + break; + } + + //portDISABLE_INTERRUPTS(); +PortDisableInt_NoNest(); + { + /* The event could have occurred just before this critical + section. If this is the case then the generic list item will + have been moved to the pending ready list and the following + line is still valid. Also the pvContainer parameter will have + been set to NULL so the following lines are also valid. */ + uxListRemove( &( pxCRCB->xGenericListItem ) ); + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pvContainer ) + { + ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); + } + } +// portENABLE_INTERRUPTS(); +PortEnableInt_NoNest(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineSchedule( void ) +{ + /* See if any co-routines readied by events need moving to the ready lists. */ + prvCheckPendingReadyList(); + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + { + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + --uxTopCoRoutineReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + + return; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseCoRoutineLists( void ) +{ +unsigned portBASE_TYPE uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + } + + vListInitialise( ( xList * ) &xDelayedCoRoutineList1 ); + vListInitialise( ( xList * ) &xDelayedCoRoutineList2 ); + vListInitialise( ( xList * ) &xPendingReadyCoRoutineList ); + + /* Start with pxDelayedCoRoutineList using list1 and the + pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList ) +{ +corCRCB *pxUnblockedCRCB; +signed portBASE_TYPE xReturn; + + /* This function is called from within an interrupt. It can only access + event lists and the pending ready list. This function assumes that a + check has already been made to ensure pxEventList is not empty. */ + pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} + diff --git a/third_party/freertos/heap_4.c b/third_party/freertos/heap_4.c index 48dbf010..5f23c931 100644 --- a/third_party/freertos/heap_4.c +++ b/third_party/freertos/heap_4.c @@ -1,707 +1,707 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -/* - * A sample implementation of pvPortMalloc() and vPortFree() that combines - * (coalescences) adjacent memory blocks as they are freed, and in so doing - * limits memory fragmentation. - * - * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the - * memory management pages of http://www.FreeRTOS.org for more information. - */ -#include -#include - -/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining -all the API functions to use the MPU wrappers. That should only be done when -task.h is included from an application file. */ -#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - -#include "espressif/esp8266/ets_sys.h" - -#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -#if 1 -#define mem_printf(fmt, args...) ets_printf(fmt,## args) -#else -#define mem_printf(fmt, args...) -#endif - -#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 0x40000000 - (uint32)&_heap_start ) ) - -/* Block sizes must not get too small. */ -#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) - -/* Assumes 8bit bytes! */ -#define heapBITS_PER_BYTE ( ( size_t ) 8 ) - -/* A few bytes might be lost to byte aligning the heap start address. */ -#define heapADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) - -/* Define the linked list structure. This is used to link free blocks in order -of their memory address. */ -typedef struct A_BLOCK_LINK -{ - struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ - size_t xBlockSize; /*<< The size of the free block. */ -#ifdef MEMLEAK_DEBUG - const char *file; - unsigned line; -#endif -} xBlockLink; - -/*-----------------------------------------------------------*/ - -/* - * Inserts a block of memory that is being freed into the correct position in - * the list of free memory blocks. The block being freed will be merged with - * the block in front it and/or the block behind it if the memory blocks are - * adjacent to each other. - */ -static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert ); - -/* - * Called automatically to setup the required heap structures the first time - * pvPortMalloc() is called. - */ -static void prvHeapInit( void ); - - -extern char _heap_start; -/*-----------------------------------------------------------*/ -/* Allocate the memory for the heap. */ -//static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; -static unsigned char *ucHeap; -/* The size of the structure placed at the beginning of each allocated memory -block must by correctly byte aligned. */ -static unsigned short heapSTRUCT_SIZE;// = ( ( sizeof ( xBlockLink ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); - -static unsigned short portBYTE_ALIGNMENT_MASK_v; -static unsigned short portBYTE_ALIGNMENT_v; - -/* Create a couple of list links to mark the start and end of the list. */ -static xBlockLink xStart, *pxEnd = NULL; - -#ifdef MEMLEAK_DEBUG -//add by jjj, we Link the used blocks here -static xBlockLink yStart; -static size_t yFreeBytesRemaining; -#endif - -/* Ensure the pxEnd pointer will end up on the correct byte alignment. */ -//static const size_t xTotalHeapSize = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); -static size_t xTotalHeapSize; - -/* Keeps track of the number of free bytes remaining, but says nothing about -fragmentation. */ -//static size_t xFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); -static size_t xFreeBytesRemaining; - -/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize -member of an xBlockLink structure is set then the block belongs to the -application. When the bit is free the block is still part of the free heap -space. */ -static size_t xBlockAllocatedBit = 0; - -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = "user_app"; -#endif - -/*-----------------------------------------------------------*/ -bool ICACHE_FLASH_ATTR __attribute__((weak)) -check_memleak_debug_enable() -{ - return 0; -} -#ifdef MEMLEAK_DEBUG -#include "spi_flash.h" -//extern SpiFlashChip *flashchip; -extern SpiFlashChip flashchip; -void prvInsertBlockIntoUsedList(xBlockLink *pxBlockToInsert) -{ - xBlockLink *pxIterator; - for( pxIterator = &yStart; pxIterator->pxNextFreeBlock < pxBlockToInsert && pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock) - { - /* Nothing to do here. */ - } - pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; - pxIterator->pxNextFreeBlock = pxBlockToInsert; - yFreeBytesRemaining += pxBlockToInsert->xBlockSize; -} - -static const char *ICACHE_FLASH_ATTR -vGetFileName(char *file_name_out, const char *file_name_in) -{ - if (((uint32)file_name_in & 0x40200000) == 0x40200000) { - uint16 str_len = ((strlen(file_name_in) - 1) / 4 + 1) * 4; - - if (str_len > 32) { - str_len = 32; - } - - memcpy(file_name_out, file_name_in, str_len); - file_name_out[str_len] = 0; - - return file_name_out; - } - - return file_name_in; -} - -void pvShowMalloc() -{ - xBlockLink *pxIterator; -//ets_printf("sh0:%d,%d,",heapSTRUCT_SIZE,sizeof( xBlockLink )); - if(heapSTRUCT_SIZE < sizeof( xBlockLink )) - return; - ETS_INTR_LOCK(); - Wait_SPI_Idle(&flashchip); - Cache_Read_Enable_New(); -//ets_printf("sh1,"); - os_printf("--------Show Malloc--------\n"); - for( pxIterator = &yStart; pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock) { - char file_name[33]; - const char *file_name_printf; -//ets_printf("sh2,"); - file_name_printf = vGetFileName(file_name, pxIterator->pxNextFreeBlock->file); - os_printf("F:%s\tL:%u\tmalloc %u\t@ %x\n", file_name_printf, pxIterator->pxNextFreeBlock->line, pxIterator->pxNextFreeBlock->xBlockSize, ( void * ) ( ( ( unsigned char * ) pxIterator->pxNextFreeBlock ) + heapSTRUCT_SIZE)); -//ets_printf("sh3,"); -// ets_delay_us(2000); - system_soft_wdt_feed(); - } - os_printf("--------Free %d--------\n\n", xFreeBytesRemaining); - -#if 0 - uint32 last_link = (uint32)yStart.pxNextFreeBlock; - uint32 index = 0; - os_printf("'*':used, '-'free, each %d bytes\n", portBYTE_ALIGNMENT_v); - os_printf("%x:", last_link); - for( pxIterator = &yStart; pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock) { - uint16 i; - for (i = 0; i < ((uint32)pxIterator->pxNextFreeBlock - last_link) / portBYTE_ALIGNMENT_v; i++) { - index++; - os_printf("-"); - if (index % 64 == 0) { - os_printf("\n%x:", (uint32)yStart.pxNextFreeBlock + index * portBYTE_ALIGNMENT_v); - } - } - for (i = 0; i < pxIterator->pxNextFreeBlock->xBlockSize / portBYTE_ALIGNMENT_v; i++) { - index++; - os_printf("*"); - if (index % 64 == 0) { - os_printf("\n%x:", (uint32)yStart.pxNextFreeBlock + index * portBYTE_ALIGNMENT_v); - } - } - last_link = ((uint32)pxIterator->pxNextFreeBlock + pxIterator->pxNextFreeBlock->xBlockSize); - system_soft_wdt_feed(); - } - os_printf("\n\n"); -#endif - -//ets_printf("sh4\n"); - ETS_INTR_UNLOCK(); -} - -void system_show_malloc(void) __attribute__((alias("pvShowMalloc"))); - -int prvRemoveBlockFromUsedList(xBlockLink *pxBlockToRemove) -{ - xBlockLink *pxIterator; - for( pxIterator = &yStart; pxIterator->pxNextFreeBlock != pxBlockToRemove && pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock) - { - /* Nothing to do here. */ - } - if(pxIterator->pxNextFreeBlock != pxBlockToRemove){ - return -1; - } - pxIterator->pxNextFreeBlock = pxBlockToRemove->pxNextFreeBlock; - yFreeBytesRemaining -= pxBlockToRemove->xBlockSize; - return 0; -} -#endif - -size_t xPortWantedSizeAlign(size_t xWantedSize) -{ - xWantedSize += heapSTRUCT_SIZE; - - /* Ensure that blocks are always aligned to the required number - of bytes. */ - if( ( xWantedSize & portBYTE_ALIGNMENT_MASK_v ) != 0x00 ) - { - /* Byte alignment required. */ - xWantedSize += ( portBYTE_ALIGNMENT_v - ( xWantedSize & portBYTE_ALIGNMENT_MASK_v ) ); - } - - return xWantedSize; -} - - -#ifndef MEMLEAK_DEBUG -void *pvPortMalloc( size_t xWantedSize ) -#else -void *pvPortMalloc( size_t xWantedSize, const char * file, unsigned line) -#endif -{ -xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink; -void *pvReturn = NULL; - -// printf("%s %d %d\n", __func__, xWantedSize, xFreeBytesRemaining); - -// vTaskSuspendAll(); - ETS_INTR_LOCK(); - { - /* If this is the first call to malloc then the heap will require - initialisation to setup the list of free blocks. */ - if( pxEnd == NULL ) - { - prvHeapInit(); - } - - if( xWantedSize > 0 ) - { - xWantedSize = xPortWantedSizeAlign(xWantedSize); - } - - if( ( xWantedSize > 0 ) && ( xWantedSize < xFreeBytesRemaining ) ) - { - /* Traverse the list from the start (lowest address) block until - one of adequate size is found. */ - pxPreviousBlock = &xStart; - pxBlock = xStart.pxNextFreeBlock; - while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) - { - pxPreviousBlock = pxBlock; - pxBlock = pxBlock->pxNextFreeBlock; - } - - /* If the end marker was reached then a block of adequate size - was not found. */ - if( pxBlock != pxEnd ) - { - /* Return the memory space pointed to - jumping over the - xBlockLink structure at its start. */ - pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); - - /* This block is being returned for use so must be taken out - of the list of free blocks. */ - pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; - - /* If the block is larger than required it can be split into - two. */ - if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) - { - /* This block is to be split into two. Create a new - block following the number of bytes requested. The void - cast is used to prevent byte alignment warnings from the - compiler. */ - pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize ); - - /* Calculate the sizes of two blocks split from the - single block. */ - pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; - pxBlock->xBlockSize = xWantedSize; - - //Insert the new block into the list of free blocks. - //ETS_INTR_LOCK(); - prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); - //ETS_INTR_UNLOCK(); - } -#ifdef MEMLEAK_DEBUG - pxBlock->pxNextFreeBlock = NULL; -#endif - xFreeBytesRemaining -= pxBlock->xBlockSize; -#ifdef MEMLEAK_DEBUG - if(heapSTRUCT_SIZE >= sizeof( xBlockLink )){ - pxBlock->file = file; - pxBlock->line = line; - } - //link the use block - prvInsertBlockIntoUsedList(pxBlock); -#endif - } - } - } -// xTaskResumeAll(); - ETS_INTR_UNLOCK(); - - #if( configUSE_MALLOC_FAILED_HOOK == 1 ) - { - if( pvReturn == NULL ) - { - //extern void vApplicationMallocFailedHook( void ); - //vApplicationMallocFailedHook(); - ets_printf("E:M %d\n", xWantedSize); - } - } - #endif -//mem_printf("%s %x\n", __func__, pvReturn); -// printf("%s %x %x\n", __func__, pvReturn, pxBlock); - return pvReturn; -} - -//void *malloc(size_t nbytes) __attribute__((alias("pvPortMalloc"))); - -/*-----------------------------------------------------------*/ -#ifndef MEMLEAK_DEBUG -void vPortFree( void *pv ) -#else -void vPortFree(void *pv, const char * file, unsigned line) -#endif -{ -unsigned char *puc = ( unsigned char * ) pv; -xBlockLink *pxLink; - -// printf("%s\n", __func__); - if( pv != NULL ) - { - /* The memory being freed will have an xBlockLink structure immediately - before it. */ - puc -= heapSTRUCT_SIZE; - - /* This casting is to keep the compiler from issuing warnings. */ - pxLink = ( void * ) puc; - -// vTaskSuspendAll(); - ETS_INTR_LOCK(); - { -#ifdef MEMLEAK_DEBUG - if(prvRemoveBlockFromUsedList(pxLink) < 0){ - ets_printf("%x already freed\n", pv); - } - else -#endif - { - /* Add this block to the list of free blocks. */ - xFreeBytesRemaining += pxLink->xBlockSize; - prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) ); - } - } -// xTaskResumeAll(); - ETS_INTR_UNLOCK(); - } - -// printf("%s %x %d\n", __func__, pv, xFreeBytesRemaining); -//mem_printf("%s %x %d\n", __func__, pv, xFreeBytesRemaining); -} - -//void free(void *ptr) __attribute__((alias("vPortFree"))); - -#ifndef MEMLEAK_DEBUG -void *malloc(size_t nbytes) __attribute__((alias("pvPortMalloc"))); -void free(void *ptr) __attribute__((alias("vPortFree"))); - -/*-----------------------------------------------------------*/ - -void *pvPortCalloc(size_t count, size_t size) -{ - void *p; - - /* allocate 'count' objects of size 'size' */ - p = pvPortMalloc(count * size); - if (p) { - /* zero the memory */ - memset(p, 0, count * size); - } - return p; -} - -void *calloc(size_t count, size_t nbytes) __attribute__((alias("pvPortCalloc"))); - -/*-----------------------------------------------------------*/ - -void *pvPortZalloc(size_t size) -{ - return pvPortCalloc(1, size); -} - -void *zalloc(size_t nbytes) __attribute__((alias("pvPortZalloc"))); - -/*-----------------------------------------------------------*/ - -void *pvPortRealloc(void *mem, size_t newsize) -{ - if (newsize == 0) { - vPortFree(mem); - return NULL; - } - - void *p; - p = pvPortMalloc(newsize); - if (p) { - /* zero the memory */ - if (mem != NULL) { - memcpy(p, mem, newsize); - vPortFree(mem); - } - } - return p; -} - -void *realloc(void *ptr, size_t nbytes) __attribute__((alias("pvPortRealloc"))); -/*-----------------------------------------------------------*/ - -#else - -/*-----------------------------------------------------------*/ -void *pvPortCalloc(size_t count, size_t size, const char * file, unsigned line) -{ - void *p; -//ets_printf("1,"); - /* allocate 'count' objects of size 'size' */ - p = pvPortMalloc(count * size, file, line); -//ets_printf("2,"); - if (p) { - /* zero the memory */ - memset(p, 0, count * size); - } -//ets_printf("3,"); - return p; -} -/*-----------------------------------------------------------*/ - -void *pvPortZalloc(size_t size, const char * file, unsigned line) -{ - return pvPortCalloc(1, size, file, line); -} -/*-----------------------------------------------------------*/ - -void *pvPortRealloc(void *mem, size_t newsize, const char *file, unsigned line) -{ - if (newsize == 0) { - vPortFree(mem, file, line); - return NULL; - } - - void *p; - p = pvPortMalloc(newsize, file, line); - if (p) { - /* zero the memory */ - if (mem != NULL) { - memcpy(p, mem, newsize); - vPortFree(mem, file, line); - } - } - return p; -} -/*-----------------------------------------------------------*/ -//For user -void *malloc(size_t nbytes) -{ -//ets_printf("u_m\n"); - return pvPortMalloc( nbytes, mem_debug_file, 0); -} - -void free(void *ptr) -{ -//ets_printf("u_f\n"); - vPortFree(ptr, mem_debug_file, 0); -} - -void *zalloc(size_t nbytes) -{ - return pvPortZalloc(nbytes, mem_debug_file, 0); -} - -void *calloc(size_t count, size_t nbytes) -{ - return pvPortCalloc(count, nbytes, mem_debug_file, 0); -} - -void *realloc(void *ptr, size_t nbytes) -{ - return pvPortRealloc(ptr, nbytes, mem_debug_file, 0); -} - -/* -void *malloc(size_t nbytes) __attribute__((alias("malloc1"))); -void free(void *ptr) __attribute__((alias("free1"))); -void *calloc(size_t count, size_t nbytes) __attribute__((alias("zalloc1"))); -void *zalloc(size_t nbytes) __attribute__((alias("calloc1"))); -void *realloc(void *ptr, size_t nbytes) __attribute__((alias("realloc1"))); -*/ -#endif - -size_t ICACHE_FLASH_ATTR -xPortGetFreeHeapSize( void ) -{ - return xFreeBytesRemaining; -} -/*-----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vPortInitialiseBlocks( void ) -{ - /* This just exists to keep the linker quiet. */ -} -/*-----------------------------------------------------------*/ - -static void prvHeapInit( void ) -{ -xBlockLink *pxFirstFreeBlock; -unsigned char *pucHeapEnd, *pucAlignedHeap; - - if( check_memleak_debug_enable() ){ - portBYTE_ALIGNMENT_MASK_v = 0xf; - portBYTE_ALIGNMENT_v = 16; - heapSTRUCT_SIZE = ( (sizeof( xBlockLink ) + portBYTE_ALIGNMENT_MASK_v)& ~portBYTE_ALIGNMENT_MASK_v); - } else { - portBYTE_ALIGNMENT_MASK_v = 0x7; - portBYTE_ALIGNMENT_v = 8; - heapSTRUCT_SIZE = 8; - } - - xFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK_v ); - xTotalHeapSize = xFreeBytesRemaining ; - ucHeap = &_heap_start; - - /* Ensure the heap starts on a correctly aligned boundary. */ - pucAlignedHeap = ( unsigned char * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT_MASK_v ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK_v ) ); - - /* xStart is used to hold a pointer to the first item in the list of free - blocks. The void cast is used to prevent compiler warnings. */ - xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; - xStart.xBlockSize = ( size_t ) 0; - - /* pxEnd is used to mark the end of the list of free blocks and is inserted - at the end of the heap space. */ - pucHeapEnd = pucAlignedHeap + xTotalHeapSize; - pucHeapEnd -= heapSTRUCT_SIZE; - pxEnd = ( void * ) pucHeapEnd; - //configASSERT( ( ( ( unsigned long ) pxEnd ) & ( ( unsigned long ) portBYTE_ALIGNMENT_MASK ) ) == 0UL ); - pxEnd->xBlockSize = 0; - pxEnd->pxNextFreeBlock = NULL; - - /* To start with there is a single free block that is sized to take up the - entire heap space, minus the space taken by pxEnd. */ - pxFirstFreeBlock = ( void * ) pucAlignedHeap; - pxFirstFreeBlock->xBlockSize = xTotalHeapSize - heapSTRUCT_SIZE; - pxFirstFreeBlock->pxNextFreeBlock = pxEnd; - - /* The heap now contains pxEnd. */ - xFreeBytesRemaining -= heapSTRUCT_SIZE; - -#ifdef MEMLEAK_DEBUG - //add by jjj - yStart.pxNextFreeBlock = NULL; - yStart.xBlockSize = ( size_t ) 0; - yFreeBytesRemaining = 0; -#endif - -} -/*-----------------------------------------------------------*/ - -static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert ) -{ -xBlockLink *pxIterator; -unsigned char *puc; - - /* Iterate through the list until a block is found that has a higher address than the block being inserted. */ - for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) - { - /* Nothing to do here, just iterate to the right position. */ - } - - /* Do the block being inserted, and the block it is being inserted after - make a contiguous block of memory? */ - puc = ( unsigned char * ) pxIterator; - if( ( puc + pxIterator->xBlockSize ) == ( unsigned char * ) pxBlockToInsert ) - { - pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; - pxBlockToInsert = pxIterator; - } - - /* Do the block being inserted, and the block it is being inserted before - make a contiguous block of memory? */ - puc = ( unsigned char * ) pxBlockToInsert; - if( ( puc + pxBlockToInsert->xBlockSize ) == ( unsigned char * ) pxIterator->pxNextFreeBlock ) - { - if( pxIterator->pxNextFreeBlock != pxEnd ) - { - /* Form one big block from the two blocks. */ - pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; - pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; - } - else - { - pxBlockToInsert->pxNextFreeBlock = pxEnd; - } - } - else - { - pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; - } - - /* If the block being inserted plugged a gab, so was merged with the block - before and the block after, then it's pxNextFreeBlock pointer will have - already been set, and should not be set here as that would make it point - to itself. */ - if( pxIterator != pxBlockToInsert ) - { - pxIterator->pxNextFreeBlock = pxBlockToInsert; - } -} - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that combines + * (coalescences) adjacent memory blocks as they are freed, and in so doing + * limits memory fragmentation. + * + * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "espressif/esp8266/ets_sys.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if 1 +#define mem_printf(fmt, args...) ets_printf(fmt,## args) +#else +#define mem_printf(fmt, args...) +#endif + +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 0x40000000 - (uint32)&_heap_start ) ) + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* A few bytes might be lost to byte aligning the heap start address. */ +#define heapADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) + +/* Define the linked list structure. This is used to link free blocks in order +of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +#ifdef MEMLEAK_DEBUG + const char *file; + unsigned line; +#endif +} xBlockLink; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert ); + +/* + * Called automatically to setup the required heap structures the first time + * pvPortMalloc() is called. + */ +static void prvHeapInit( void ); + + +extern char _heap_start; +/*-----------------------------------------------------------*/ +/* Allocate the memory for the heap. */ +//static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; +static unsigned char *ucHeap; +/* The size of the structure placed at the beginning of each allocated memory +block must by correctly byte aligned. */ +static unsigned short heapSTRUCT_SIZE;// = ( ( sizeof ( xBlockLink ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); + +static unsigned short portBYTE_ALIGNMENT_MASK_v; +static unsigned short portBYTE_ALIGNMENT_v; + +/* Create a couple of list links to mark the start and end of the list. */ +static xBlockLink xStart, *pxEnd = NULL; + +#ifdef MEMLEAK_DEBUG +//add by jjj, we Link the used blocks here +static xBlockLink yStart; +static size_t yFreeBytesRemaining; +#endif + +/* Ensure the pxEnd pointer will end up on the correct byte alignment. */ +//static const size_t xTotalHeapSize = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); +static size_t xTotalHeapSize; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +//static size_t xFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); +static size_t xFreeBytesRemaining; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize +member of an xBlockLink structure is set then the block belongs to the +application. When the bit is free the block is still part of the free heap +space. */ +static size_t xBlockAllocatedBit = 0; + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = "user_app"; +#endif + +/*-----------------------------------------------------------*/ +bool ICACHE_FLASH_ATTR __attribute__((weak)) +check_memleak_debug_enable() +{ + return 0; +} +#ifdef MEMLEAK_DEBUG +#include "spi_flash.h" +//extern SpiFlashChip *flashchip; +extern SpiFlashChip flashchip; +void prvInsertBlockIntoUsedList(xBlockLink *pxBlockToInsert) +{ + xBlockLink *pxIterator; + for( pxIterator = &yStart; pxIterator->pxNextFreeBlock < pxBlockToInsert && pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock) + { + /* Nothing to do here. */ + } + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + pxIterator->pxNextFreeBlock = pxBlockToInsert; + yFreeBytesRemaining += pxBlockToInsert->xBlockSize; +} + +static const char *ICACHE_FLASH_ATTR +vGetFileName(char *file_name_out, const char *file_name_in) +{ + if (((uint32)file_name_in & 0x40200000) == 0x40200000) { + uint16 str_len = ((strlen(file_name_in) - 1) / 4 + 1) * 4; + + if (str_len > 32) { + str_len = 32; + } + + memcpy(file_name_out, file_name_in, str_len); + file_name_out[str_len] = 0; + + return file_name_out; + } + + return file_name_in; +} + +void pvShowMalloc() +{ + xBlockLink *pxIterator; +//ets_printf("sh0:%d,%d,",heapSTRUCT_SIZE,sizeof( xBlockLink )); + if(heapSTRUCT_SIZE < sizeof( xBlockLink )) + return; + ETS_INTR_LOCK(); + Wait_SPI_Idle(&flashchip); + Cache_Read_Enable_New(); +//ets_printf("sh1,"); + os_printf("--------Show Malloc--------\n"); + for( pxIterator = &yStart; pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock) { + char file_name[33]; + const char *file_name_printf; +//ets_printf("sh2,"); + file_name_printf = vGetFileName(file_name, pxIterator->pxNextFreeBlock->file); + os_printf("F:%s\tL:%u\tmalloc %u\t@ %x\n", file_name_printf, pxIterator->pxNextFreeBlock->line, pxIterator->pxNextFreeBlock->xBlockSize, ( void * ) ( ( ( unsigned char * ) pxIterator->pxNextFreeBlock ) + heapSTRUCT_SIZE)); +//ets_printf("sh3,"); +// ets_delay_us(2000); + system_soft_wdt_feed(); + } + os_printf("--------Free %d--------\n\n", xFreeBytesRemaining); + +#if 0 + uint32 last_link = (uint32)yStart.pxNextFreeBlock; + uint32 index = 0; + os_printf("'*':used, '-'free, each %d bytes\n", portBYTE_ALIGNMENT_v); + os_printf("%x:", last_link); + for( pxIterator = &yStart; pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock) { + uint16 i; + for (i = 0; i < ((uint32)pxIterator->pxNextFreeBlock - last_link) / portBYTE_ALIGNMENT_v; i++) { + index++; + os_printf("-"); + if (index % 64 == 0) { + os_printf("\n%x:", (uint32)yStart.pxNextFreeBlock + index * portBYTE_ALIGNMENT_v); + } + } + for (i = 0; i < pxIterator->pxNextFreeBlock->xBlockSize / portBYTE_ALIGNMENT_v; i++) { + index++; + os_printf("*"); + if (index % 64 == 0) { + os_printf("\n%x:", (uint32)yStart.pxNextFreeBlock + index * portBYTE_ALIGNMENT_v); + } + } + last_link = ((uint32)pxIterator->pxNextFreeBlock + pxIterator->pxNextFreeBlock->xBlockSize); + system_soft_wdt_feed(); + } + os_printf("\n\n"); +#endif + +//ets_printf("sh4\n"); + ETS_INTR_UNLOCK(); +} + +void system_show_malloc(void) __attribute__((alias("pvShowMalloc"))); + +int prvRemoveBlockFromUsedList(xBlockLink *pxBlockToRemove) +{ + xBlockLink *pxIterator; + for( pxIterator = &yStart; pxIterator->pxNextFreeBlock != pxBlockToRemove && pxIterator->pxNextFreeBlock != NULL;pxIterator = pxIterator->pxNextFreeBlock) + { + /* Nothing to do here. */ + } + if(pxIterator->pxNextFreeBlock != pxBlockToRemove){ + return -1; + } + pxIterator->pxNextFreeBlock = pxBlockToRemove->pxNextFreeBlock; + yFreeBytesRemaining -= pxBlockToRemove->xBlockSize; + return 0; +} +#endif + +size_t xPortWantedSizeAlign(size_t xWantedSize) +{ + xWantedSize += heapSTRUCT_SIZE; + + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK_v ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT_v - ( xWantedSize & portBYTE_ALIGNMENT_MASK_v ) ); + } + + return xWantedSize; +} + + +#ifndef MEMLEAK_DEBUG +void *pvPortMalloc( size_t xWantedSize ) +#else +void *pvPortMalloc( size_t xWantedSize, const char * file, unsigned line) +#endif +{ +xBlockLink *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +void *pvReturn = NULL; + +// printf("%s %d %d\n", __func__, xWantedSize, xFreeBytesRemaining); + +// vTaskSuspendAll(); + ETS_INTR_LOCK(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( pxEnd == NULL ) + { + prvHeapInit(); + } + + if( xWantedSize > 0 ) + { + xWantedSize = xPortWantedSizeAlign(xWantedSize); + } + + if( ( xWantedSize > 0 ) && ( xWantedSize < xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + was not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + xBlockLink structure at its start. */ + pvReturn = ( void * ) ( ( ( unsigned char * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); + + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = ( void * ) ( ( ( unsigned char * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + //Insert the new block into the list of free blocks. + //ETS_INTR_LOCK(); + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + //ETS_INTR_UNLOCK(); + } +#ifdef MEMLEAK_DEBUG + pxBlock->pxNextFreeBlock = NULL; +#endif + xFreeBytesRemaining -= pxBlock->xBlockSize; +#ifdef MEMLEAK_DEBUG + if(heapSTRUCT_SIZE >= sizeof( xBlockLink )){ + pxBlock->file = file; + pxBlock->line = line; + } + //link the use block + prvInsertBlockIntoUsedList(pxBlock); +#endif + } + } + } +// xTaskResumeAll(); + ETS_INTR_UNLOCK(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + //extern void vApplicationMallocFailedHook( void ); + //vApplicationMallocFailedHook(); + ets_printf("E:M %d\n", xWantedSize); + } + } + #endif +//mem_printf("%s %x\n", __func__, pvReturn); +// printf("%s %x %x\n", __func__, pvReturn, pxBlock); + return pvReturn; +} + +//void *malloc(size_t nbytes) __attribute__((alias("pvPortMalloc"))); + +/*-----------------------------------------------------------*/ +#ifndef MEMLEAK_DEBUG +void vPortFree( void *pv ) +#else +void vPortFree(void *pv, const char * file, unsigned line) +#endif +{ +unsigned char *puc = ( unsigned char * ) pv; +xBlockLink *pxLink; + +// printf("%s\n", __func__); + if( pv != NULL ) + { + /* The memory being freed will have an xBlockLink structure immediately + before it. */ + puc -= heapSTRUCT_SIZE; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + +// vTaskSuspendAll(); + ETS_INTR_LOCK(); + { +#ifdef MEMLEAK_DEBUG + if(prvRemoveBlockFromUsedList(pxLink) < 0){ + ets_printf("%x already freed\n", pv); + } + else +#endif + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) ); + } + } +// xTaskResumeAll(); + ETS_INTR_UNLOCK(); + } + +// printf("%s %x %d\n", __func__, pv, xFreeBytesRemaining); +//mem_printf("%s %x %d\n", __func__, pv, xFreeBytesRemaining); +} + +//void free(void *ptr) __attribute__((alias("vPortFree"))); + +#ifndef MEMLEAK_DEBUG +void *malloc(size_t nbytes) __attribute__((alias("pvPortMalloc"))); +void free(void *ptr) __attribute__((alias("vPortFree"))); + +/*-----------------------------------------------------------*/ + +void *pvPortCalloc(size_t count, size_t size) +{ + void *p; + + /* allocate 'count' objects of size 'size' */ + p = pvPortMalloc(count * size); + if (p) { + /* zero the memory */ + memset(p, 0, count * size); + } + return p; +} + +void *calloc(size_t count, size_t nbytes) __attribute__((alias("pvPortCalloc"))); + +/*-----------------------------------------------------------*/ + +void *pvPortZalloc(size_t size) +{ + return pvPortCalloc(1, size); +} + +void *zalloc(size_t nbytes) __attribute__((alias("pvPortZalloc"))); + +/*-----------------------------------------------------------*/ + +void *pvPortRealloc(void *mem, size_t newsize) +{ + if (newsize == 0) { + vPortFree(mem); + return NULL; + } + + void *p; + p = pvPortMalloc(newsize); + if (p) { + /* zero the memory */ + if (mem != NULL) { + memcpy(p, mem, newsize); + vPortFree(mem); + } + } + return p; +} + +void *realloc(void *ptr, size_t nbytes) __attribute__((alias("pvPortRealloc"))); +/*-----------------------------------------------------------*/ + +#else + +/*-----------------------------------------------------------*/ +void *pvPortCalloc(size_t count, size_t size, const char * file, unsigned line) +{ + void *p; +//ets_printf("1,"); + /* allocate 'count' objects of size 'size' */ + p = pvPortMalloc(count * size, file, line); +//ets_printf("2,"); + if (p) { + /* zero the memory */ + memset(p, 0, count * size); + } +//ets_printf("3,"); + return p; +} +/*-----------------------------------------------------------*/ + +void *pvPortZalloc(size_t size, const char * file, unsigned line) +{ + return pvPortCalloc(1, size, file, line); +} +/*-----------------------------------------------------------*/ + +void *pvPortRealloc(void *mem, size_t newsize, const char *file, unsigned line) +{ + if (newsize == 0) { + vPortFree(mem, file, line); + return NULL; + } + + void *p; + p = pvPortMalloc(newsize, file, line); + if (p) { + /* zero the memory */ + if (mem != NULL) { + memcpy(p, mem, newsize); + vPortFree(mem, file, line); + } + } + return p; +} +/*-----------------------------------------------------------*/ +//For user +void *malloc(size_t nbytes) +{ +//ets_printf("u_m\n"); + return pvPortMalloc( nbytes, mem_debug_file, 0); +} + +void free(void *ptr) +{ +//ets_printf("u_f\n"); + vPortFree(ptr, mem_debug_file, 0); +} + +void *zalloc(size_t nbytes) +{ + return pvPortZalloc(nbytes, mem_debug_file, 0); +} + +void *calloc(size_t count, size_t nbytes) +{ + return pvPortCalloc(count, nbytes, mem_debug_file, 0); +} + +void *realloc(void *ptr, size_t nbytes) +{ + return pvPortRealloc(ptr, nbytes, mem_debug_file, 0); +} + +/* +void *malloc(size_t nbytes) __attribute__((alias("malloc1"))); +void free(void *ptr) __attribute__((alias("free1"))); +void *calloc(size_t count, size_t nbytes) __attribute__((alias("zalloc1"))); +void *zalloc(size_t nbytes) __attribute__((alias("calloc1"))); +void *realloc(void *ptr, size_t nbytes) __attribute__((alias("realloc1"))); +*/ +#endif + +size_t ICACHE_FLASH_ATTR +xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ +xBlockLink *pxFirstFreeBlock; +unsigned char *pucHeapEnd, *pucAlignedHeap; + + if( check_memleak_debug_enable() ){ + portBYTE_ALIGNMENT_MASK_v = 0xf; + portBYTE_ALIGNMENT_v = 16; + heapSTRUCT_SIZE = ( (sizeof( xBlockLink ) + portBYTE_ALIGNMENT_MASK_v)& ~portBYTE_ALIGNMENT_MASK_v); + } else { + portBYTE_ALIGNMENT_MASK_v = 0x7; + portBYTE_ALIGNMENT_v = 8; + heapSTRUCT_SIZE = 8; + } + + xFreeBytesRemaining = ( ( size_t ) heapADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK_v ); + xTotalHeapSize = xFreeBytesRemaining ; + ucHeap = &_heap_start; + + /* Ensure the heap starts on a correctly aligned boundary. */ + pucAlignedHeap = ( unsigned char * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT_MASK_v ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK_v ) ); + + /* xStart is used to hold a pointer to the first item in the list of free + blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* pxEnd is used to mark the end of the list of free blocks and is inserted + at the end of the heap space. */ + pucHeapEnd = pucAlignedHeap + xTotalHeapSize; + pucHeapEnd -= heapSTRUCT_SIZE; + pxEnd = ( void * ) pucHeapEnd; + //configASSERT( ( ( ( unsigned long ) pxEnd ) & ( ( unsigned long ) portBYTE_ALIGNMENT_MASK ) ) == 0UL ); + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + entire heap space, minus the space taken by pxEnd. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = xTotalHeapSize - heapSTRUCT_SIZE; + pxFirstFreeBlock->pxNextFreeBlock = pxEnd; + + /* The heap now contains pxEnd. */ + xFreeBytesRemaining -= heapSTRUCT_SIZE; + +#ifdef MEMLEAK_DEBUG + //add by jjj + yStart.pxNextFreeBlock = NULL; + yStart.xBlockSize = ( size_t ) 0; + yFreeBytesRemaining = 0; +#endif + +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( xBlockLink *pxBlockToInsert ) +{ +xBlockLink *pxIterator; +unsigned char *puc; + + /* Iterate through the list until a block is found that has a higher address than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = ( unsigned char * ) pxIterator; + if( ( puc + pxIterator->xBlockSize ) == ( unsigned char * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = ( unsigned char * ) pxBlockToInsert; + if( ( puc + pxBlockToInsert->xBlockSize ) == ( unsigned char * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } +} + diff --git a/third_party/freertos/list.c b/third_party/freertos/list.c index c6b23d07..326b3d6d 100644 --- a/third_party/freertos/list.c +++ b/third_party/freertos/list.c @@ -1,208 +1,208 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - - -#include -#include "freertos/FreeRTOS.h" -#include "freertos/list.h" - -/*----------------------------------------------------------- - * PUBLIC LIST API documented in list.h - *----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vListInitialise( xList * const pxList ) -{ - /* The list structure contains a list item which is used to mark the - end of the list. To initialise the list the list end is inserted - as the only list entry. */ - pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ - - /* The list end value is the highest possible value in the list to - ensure it remains at the end of the list. */ - pxList->xListEnd.xItemValue = portMAX_DELAY; - - /* The list end next and previous pointers point to itself so we know - when the list is empty. */ - pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ - pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ - - pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U; -} -/*-----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vListInitialiseItem( xListItem * const pxItem ) -{ - /* Make sure the list item is not recorded as being on a list. */ - pxItem->pvContainer = NULL; -} -/*-----------------------------------------------------------*/ - -void -vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem ) -{ -xListItem * pxIndex; - - /* Insert a new list item into pxList, but rather than sort the list, - makes the new list item the last item to be removed by a call to - pvListGetOwnerOfNextEntry. */ - pxIndex = pxList->pxIndex; - - pxNewListItem->pxNext = pxIndex; - pxNewListItem->pxPrevious = pxIndex->pxPrevious; - pxIndex->pxPrevious->pxNext = pxNewListItem; - pxIndex->pxPrevious = pxNewListItem; - - /* Remember which list the item is in. */ - pxNewListItem->pvContainer = ( void * ) pxList; - - ( pxList->uxNumberOfItems )++; -} -/*-----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vListInsert( xList * const pxList, xListItem * const pxNewListItem ) -{ -xListItem *pxIterator; -portTickType xValueOfInsertion; - - /* Insert the new list item into the list, sorted in ulListItem order. */ - xValueOfInsertion = pxNewListItem->xItemValue; - - /* If the list already contains a list item with the same item value then - the new list item should be placed after it. This ensures that TCB's which - are stored in ready lists (all of which have the same ulListItem value) - get an equal share of the CPU. However, if the xItemValue is the same as - the back marker the iteration loop below will not end. This means we need - to guard against this by checking the value first and modifying the - algorithm slightly if necessary. */ - if( xValueOfInsertion == portMAX_DELAY ) - { - pxIterator = pxList->xListEnd.pxPrevious; - } - else - { - /* *** NOTE *********************************************************** - If you find your application is crashing here then likely causes are: - 1) Stack overflow - - see http://www.freertos.org/Stacks-and-stack-overflow-checking.html - 2) Incorrect interrupt priority assignment, especially on Cortex-M3 - parts where numerically high priority values denote low actual - interrupt priories, which can seem counter intuitive. See - configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html - 3) Calling an API function from within a critical section or when - the scheduler is suspended, or calling an API function that does - not end in "FromISR" from an interrupt. - 4) Using a queue or semaphore before it has been initialised or - before the scheduler has been started (are interrupts firing - before vTaskStartScheduler() has been called?). - See http://www.freertos.org/FAQHelp.html for more tips. - **********************************************************************/ - - for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ - { - /* There is nothing to do here, we are just iterating to the - wanted insertion position. */ - } - } - - pxNewListItem->pxNext = pxIterator->pxNext; - pxNewListItem->pxNext->pxPrevious = pxNewListItem; - pxNewListItem->pxPrevious = pxIterator; - pxIterator->pxNext = pxNewListItem; - - /* Remember which list the item is in. This allows fast removal of the - item later. */ - pxNewListItem->pvContainer = ( void * ) pxList; - - ( pxList->uxNumberOfItems )++; -} -/*-----------------------------------------------------------*/ - -unsigned portBASE_TYPE -uxListRemove( xListItem * const pxItemToRemove ) -{ -xList * pxList; - - pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; - pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; - - /* The list item knows which list it is in. Obtain the list from the list - item. */ - pxList = ( xList * ) pxItemToRemove->pvContainer; - - /* Make sure the index is left pointing to a valid item. */ - if( pxList->pxIndex == pxItemToRemove ) - { - pxList->pxIndex = pxItemToRemove->pxPrevious; - } - - pxItemToRemove->pvContainer = NULL; - ( pxList->uxNumberOfItems )--; - - return pxList->uxNumberOfItems; -} -/*-----------------------------------------------------------*/ - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/list.h" + +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vListInitialise( xList * const pxList ) +{ + /* The list structure contains a list item which is used to mark the + end of the list. To initialise the list the list end is inserted + as the only list entry. */ + pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + /* The list end value is the highest possible value in the list to + ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + + /* The list end next and previous pointers point to itself so we know + when the list is empty. */ + pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U; +} +/*-----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vListInitialiseItem( xListItem * const pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pvContainer = NULL; +} +/*-----------------------------------------------------------*/ + +void +vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem ) +{ +xListItem * pxIndex; + + /* Insert a new list item into pxList, but rather than sort the list, + makes the new list item the last item to be removed by a call to + pvListGetOwnerOfNextEntry. */ + pxIndex = pxList->pxIndex; + + pxNewListItem->pxNext = pxIndex; + pxNewListItem->pxPrevious = pxIndex->pxPrevious; + pxIndex->pxPrevious->pxNext = pxNewListItem; + pxIndex->pxPrevious = pxNewListItem; + + /* Remember which list the item is in. */ + pxNewListItem->pvContainer = ( void * ) pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vListInsert( xList * const pxList, xListItem * const pxNewListItem ) +{ +xListItem *pxIterator; +portTickType xValueOfInsertion; + + /* Insert the new list item into the list, sorted in ulListItem order. */ + xValueOfInsertion = pxNewListItem->xItemValue; + + /* If the list already contains a list item with the same item value then + the new list item should be placed after it. This ensures that TCB's which + are stored in ready lists (all of which have the same ulListItem value) + get an equal share of the CPU. However, if the xItemValue is the same as + the back marker the iteration loop below will not end. This means we need + to guard against this by checking the value first and modifying the + algorithm slightly if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + { + pxIterator = pxList->xListEnd.pxPrevious; + } + else + { + /* *** NOTE *********************************************************** + If you find your application is crashing here then likely causes are: + 1) Stack overflow - + see http://www.freertos.org/Stacks-and-stack-overflow-checking.html + 2) Incorrect interrupt priority assignment, especially on Cortex-M3 + parts where numerically high priority values denote low actual + interrupt priories, which can seem counter intuitive. See + configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html + 3) Calling an API function from within a critical section or when + the scheduler is suspended, or calling an API function that does + not end in "FromISR" from an interrupt. + 4) Using a queue or semaphore before it has been initialised or + before the scheduler has been started (are interrupts firing + before vTaskStartScheduler() has been called?). + See http://www.freertos.org/FAQHelp.html for more tips. + **********************************************************************/ + + for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + { + /* There is nothing to do here, we are just iterating to the + wanted insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + pxNewListItem->pxNext->pxPrevious = pxNewListItem; + pxNewListItem->pxPrevious = pxIterator; + pxIterator->pxNext = pxNewListItem; + + /* Remember which list the item is in. This allows fast removal of the + item later. */ + pxNewListItem->pvContainer = ( void * ) pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE +uxListRemove( xListItem * const pxItemToRemove ) +{ +xList * pxList; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + + /* The list item knows which list it is in. Obtain the list from the list + item. */ + pxList = ( xList * ) pxItemToRemove->pvContainer; + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + } + + pxItemToRemove->pvContainer = NULL; + ( pxList->uxNumberOfItems )--; + + return pxList->uxNumberOfItems; +} +/*-----------------------------------------------------------*/ + diff --git a/third_party/freertos/queue.c b/third_party/freertos/queue.c index 8b316c3e..6fbe19a2 100644 --- a/third_party/freertos/queue.c +++ b/third_party/freertos/queue.c @@ -1,2130 +1,2130 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -#include -#include - -/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining -all the API functions to use the MPU wrappers. That should only be done when -task.h is included from an application file. */ -#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" - -#if ( configUSE_CO_ROUTINES == 1 ) - #include "freertos/croutine.h" -#endif - -/* Lint e961 and e750 are suppressed as a MISRA exception justified because the -MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the -header files above, but not in this file, in order to generate the correct -privileged Vs unprivileged linkage and placement. */ -#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ - - -/* Constants used with the cRxLock and xTxLock structure members. */ -#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 ) -#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 ) - -/* When the xQUEUE structure is used to represent a base queue its pcHead and -pcTail members are used as pointers into the queue storage area. When the -xQUEUE structure is used to represent a mutex pcHead and pcTail pointers are -not necessary, and the pcHead pointer is set to NULL to indicate that the -pcTail pointer actually points to the mutex holder (if any). Map alternative -names to the pcHead and pcTail structure members to ensure the readability of -the code is maintained despite this dual use of two structure members. An -alternative implementation would be to use a union, but use of a union is -against the coding standard (although an exception to the standard has been -permitted where the dual use also significantly changes the type of the -structure member). */ -#define pxMutexHolder pcTail -#define uxQueueType pcHead -#define queueQUEUE_IS_MUTEX NULL - -/* Semaphores do not actually store or copy data, so have an item size of -zero. */ -#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 ) -#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0U ) - -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - - -/* - * Definition of the queue used by the scheduler. - * Items are queued by copy, not reference. - */ -typedef struct QueueDefinition -{ - signed char *pcHead; /*< Points to the beginning of the queue storage area. */ - signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ - - signed char *pcWriteTo; /*< Points to the free next place in the storage area. */ - - union /* Use of a union is an exception to the coding standard to ensure two mutually exclusive structure members don't appear simultaneously (wasting RAM). */ - { - signed char *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */ - unsigned portBASE_TYPE uxRecursiveCallCount;/*< Maintains a count of the numebr of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ - } u; - - xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ - xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ - - volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */ - unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ - unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */ - - volatile signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ - volatile signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ - - #if ( configUSE_TRACE_FACILITY == 1 ) - unsigned char ucQueueNumber; - unsigned char ucQueueType; - #endif - - #if ( configUSE_QUEUE_SETS == 1 ) - struct QueueDefinition *pxQueueSetContainer; - #endif - -} xQUEUE; -/*-----------------------------------------------------------*/ - -/* - * The queue registry is just a means for kernel aware debuggers to locate - * queue structures. It has no other purpose so is an optional component. - */ -#if ( configQUEUE_REGISTRY_SIZE > 0 ) - - /* The type stored within the queue registry array. This allows a name - to be assigned to each queue making kernel aware debugging a little - more user friendly. */ - typedef struct QUEUE_REGISTRY_ITEM - { - signed char *pcQueueName; - xQueueHandle xHandle; - } xQueueRegistryItem; - - /* The queue registry is simply an array of xQueueRegistryItem structures. - The pcQueueName member of a structure being NULL is indicative of the - array position being vacant. */ - xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; - -#endif /* configQUEUE_REGISTRY_SIZE */ - -/* - * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not - * prevent an ISR from adding or removing items to the queue, but does prevent - * an ISR from removing tasks from the queue event lists. If an ISR finds a - * queue is locked it will instead increment the appropriate queue lock count - * to indicate that a task may require unblocking. When the queue in unlocked - * these lock counts are inspected, and the appropriate action taken. - */ -static void prvUnlockQueue( xQUEUE *pxQueue ) PRIVILEGED_FUNCTION; - -/* - * Uses a critical section to determine if there is any data in a queue. - * - * @return pdTRUE if the queue contains no items, otherwise pdFALSE. - */ -static signed portBASE_TYPE prvIsQueueEmpty( const xQUEUE *pxQueue ) PRIVILEGED_FUNCTION; - -/* - * Uses a critical section to determine if there is any space in a queue. - * - * @return pdTRUE if there is no space, otherwise pdFALSE; - */ -static signed portBASE_TYPE prvIsQueueFull( const xQUEUE *pxQueue ) PRIVILEGED_FUNCTION; - -/* - * Copies an item into the queue, either at the front of the queue or the - * back of the queue. - */ -static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION; - -/* - * Copies an item out of a queue. - */ -static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void * const pvBuffer ) PRIVILEGED_FUNCTION; - -#if ( configUSE_QUEUE_SETS == 1 ) - /* - * Checks to see if a queue is a member of a queue set, and if so, notifies - * the queue set that the queue contains data. - */ - static portBASE_TYPE prvNotifyQueueSetContainer( const xQUEUE * const pxQueue, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; -#endif - -/*-----------------------------------------------------------*/ - -/* - * Macro to mark a queue as locked. Locking a queue prevents an ISR from - * accessing the queue event lists. - */ -#define prvLockQueue( pxQueue ) \ - taskENTER_CRITICAL(); \ - { \ - if( ( pxQueue )->xRxLock == queueUNLOCKED ) \ - { \ - ( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \ - } \ - if( ( pxQueue )->xTxLock == queueUNLOCKED ) \ - { \ - ( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \ - } \ - } \ - taskEXIT_CRITICAL() -/*-----------------------------------------------------------*/ - -portBASE_TYPE ICACHE_FLASH_ATTR -xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue ) -{ -xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - configASSERT( pxQueue ); - - taskENTER_CRITICAL(); - { - pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); - pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U; - pxQueue->pcWriteTo = pxQueue->pcHead; - pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize ); - pxQueue->xRxLock = queueUNLOCKED; - pxQueue->xTxLock = queueUNLOCKED; - - if( xNewQueue == pdFALSE ) - { - /* If there are tasks blocked waiting to read from the queue, then - the tasks will remain blocked as after this function exits the queue - will still be empty. If there are tasks blocked waiting to write to - the queue, then one should be unblocked as after this function exits - it will be possible to write to it. */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) - { - portYIELD_WITHIN_API(); - } - } - } - else - { - /* Ensure the event queues start in the correct state. */ - vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); - vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); - } - } - taskEXIT_CRITICAL(); - - /* A value is returned for calling semantic consistency with previous - versions. */ - return pdPASS; -} -/*-----------------------------------------------------------*/ - -xQueueHandle ICACHE_FLASH_ATTR -xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) -{ -xQUEUE *pxNewQueue; -size_t xQueueSizeInBytes; -xQueueHandle xReturn = NULL; - - /* Remove compiler warnings about unused parameters should - configUSE_TRACE_FACILITY not be set to 1. */ - ( void ) ucQueueType; - - /* Allocate the new queue structure. */ - if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 ) - { - pxNewQueue = ( xQUEUE * ) os_malloc( sizeof( xQUEUE ) ); - if( pxNewQueue != NULL ) - { - /* Create the list of pointers to queue items. The queue is one byte - longer than asked for to make wrap checking easier/faster. */ - xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - - pxNewQueue->pcHead = ( signed char * ) os_malloc( xQueueSizeInBytes ); - if( pxNewQueue->pcHead != NULL ) - { - /* Initialise the queue members as described above where the - queue type is defined. */ - pxNewQueue->uxLength = uxQueueLength; - pxNewQueue->uxItemSize = uxItemSize; - ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); - - #if ( configUSE_TRACE_FACILITY == 1 ) - { - pxNewQueue->ucQueueType = ucQueueType; - } - #endif /* configUSE_TRACE_FACILITY */ - - #if( configUSE_QUEUE_SETS == 1 ) - { - pxNewQueue->pxQueueSetContainer = NULL; - } - #endif /* configUSE_QUEUE_SETS */ - - traceQUEUE_CREATE( pxNewQueue ); - xReturn = pxNewQueue; - } - else - { - traceQUEUE_CREATE_FAILED( ucQueueType ); - os_free( pxNewQueue ); - } - } - } - - configASSERT( xReturn ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -#if ( configUSE_MUTEXES == 1 ) - - xQueueHandle ICACHE_FLASH_ATTR - xQueueCreateMutex( unsigned char ucQueueType ) - { - xQUEUE *pxNewQueue; - - /* Prevent compiler warnings about unused parameters if - configUSE_TRACE_FACILITY does not equal 1. */ - ( void ) ucQueueType; - - /* Allocate the new queue structure. */ - pxNewQueue = ( xQUEUE * ) os_malloc( sizeof( xQUEUE ) ); - if( pxNewQueue != NULL ) - { - /* Information required for priority inheritance. */ - pxNewQueue->pxMutexHolder = NULL; - pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; - - /* Queues used as a mutex no data is actually copied into or out - of the queue. */ - pxNewQueue->pcWriteTo = NULL; - pxNewQueue->u.pcReadFrom = NULL; - - /* Each mutex has a length of 1 (like a binary semaphore) and - an item size of 0 as nothing is actually copied into or out - of the mutex. */ - pxNewQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U; - pxNewQueue->uxLength = ( unsigned portBASE_TYPE ) 1U; - pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U; - pxNewQueue->xRxLock = queueUNLOCKED; - pxNewQueue->xTxLock = queueUNLOCKED; - - #if ( configUSE_TRACE_FACILITY == 1 ) - { - pxNewQueue->ucQueueType = ucQueueType; - } - #endif - - #if ( configUSE_QUEUE_SETS == 1 ) - { - pxNewQueue->pxQueueSetContainer = NULL; - } - #endif - - /* Ensure the event queues start with the correct state. */ - vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); - vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); - - traceCREATE_MUTEX( pxNewQueue ); - - /* Start with the semaphore in the expected state. */ - ( void ) xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK ); - } - else - { - traceCREATE_MUTEX_FAILED(); - } - - configASSERT( pxNewQueue ); - return pxNewQueue; - } - -#endif /* configUSE_MUTEXES */ -/*-----------------------------------------------------------*/ - -#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) - - void* ICACHE_FLASH_ATTR - xQueueGetMutexHolder( xQueueHandle xSemaphore ) - { - void *pxReturn; - - /* This function is called by xSemaphoreGetMutexHolder(), and should not - be called directly. Note: This is is a good way of determining if the - calling task is the mutex holder, but not a good way of determining the - identity of the mutex holder, as the holder may change between the - following critical section exiting and the function returning. */ - taskENTER_CRITICAL(); - { - if( ( ( xQUEUE * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX ) - { - pxReturn = ( void * ) ( ( xQUEUE * ) xSemaphore )->pxMutexHolder; - } - else - { - pxReturn = NULL; - } - } - taskEXIT_CRITICAL(); - - return pxReturn; - } - -#endif -/*-----------------------------------------------------------*/ - -#if ( configUSE_RECURSIVE_MUTEXES == 1 ) - - portBASE_TYPE ICACHE_FLASH_ATTR - xQueueGiveMutexRecursive( xQueueHandle xMutex ) - { - portBASE_TYPE xReturn; - xQUEUE * const pxMutex = ( xQUEUE * ) xMutex; - - configASSERT( pxMutex ); - - /* If this is the task that holds the mutex then pxMutexHolder will not - change outside of this task. If this task does not hold the mutex then - pxMutexHolder can never coincidentally equal the tasks handle, and as - this is the only condition we are interested in it does not matter if - pxMutexHolder is accessed simultaneously by another task. Therefore no - mutual exclusion is required to test the pxMutexHolder variable. */ - if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Not a redundant cast as xTaskHandle is a typedef. */ - { - traceGIVE_MUTEX_RECURSIVE( pxMutex ); - - /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to - the task handle, therefore no underflow check is required. Also, - uxRecursiveCallCount is only modified by the mutex holder, and as - there can only be one, no mutual exclusion is required to modify the - uxRecursiveCallCount member. */ - ( pxMutex->u.uxRecursiveCallCount )--; - - /* Have we unwound the call count? */ - if( pxMutex->u.uxRecursiveCallCount == ( unsigned portBASE_TYPE ) 0 ) - { - /* Return the mutex. This will automatically unblock any other - task that might be waiting to access the mutex. */ - ( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); - } - - xReturn = pdPASS; - } - else - { - /* We cannot give the mutex because we are not the holder. */ - xReturn = pdFAIL; - - traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ); - } - - return xReturn; - } - -#endif /* configUSE_RECURSIVE_MUTEXES */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_RECURSIVE_MUTEXES == 1 ) - - portBASE_TYPE ICACHE_FLASH_ATTR - xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) - { - portBASE_TYPE xReturn; - xQUEUE * const pxMutex = ( xQUEUE * ) xMutex; - - configASSERT( pxMutex ); - - /* Comments regarding mutual exclusion as per those within - xQueueGiveMutexRecursive(). */ - - traceTAKE_MUTEX_RECURSIVE( pxMutex ); - - if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Cast is not redundant as xTaskHandle is a typedef. */ - { - ( pxMutex->u.uxRecursiveCallCount )++; - xReturn = pdPASS; - } - else - { - xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE ); - - /* pdPASS will only be returned if we successfully obtained the mutex, - we may have blocked to reach here. */ - if( xReturn == pdPASS ) - { - ( pxMutex->u.uxRecursiveCallCount )++; - } - else - { - traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); - } - } - - return xReturn; - } - -#endif /* configUSE_RECURSIVE_MUTEXES */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_COUNTING_SEMAPHORES == 1 ) - - xQueueHandle ICACHE_FLASH_ATTR - xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) - { - xQueueHandle xHandle; - - xHandle = xQueueGenericCreate( uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); - - if( xHandle != NULL ) - { - ( ( xQUEUE * ) xHandle )->uxMessagesWaiting = uxInitialCount; - - traceCREATE_COUNTING_SEMAPHORE(); - } - else - { - traceCREATE_COUNTING_SEMAPHORE_FAILED(); - } - - configASSERT( xHandle ); - return xHandle; - } - -#endif /* configUSE_COUNTING_SEMAPHORES */ -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE ICACHE_FLASH_ATTR -xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) -{ -signed portBASE_TYPE xEntryTimeSet = pdFALSE; -xTimeOutType xTimeOut; -xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - configASSERT( pxQueue ); - configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); - - /* This function relaxes the coding standard somewhat to allow return - statements within the function itself. This is done in the interest - of execution time efficiency. */ - for( ;; ) - { - taskENTER_CRITICAL(); - { - /* Is there room on the queue now? The running task must be - the highest priority task wanting to access the queue. If - the head item in the queue is to be overwritten then it does - not matter if the queue is full. */ - if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) - { - traceQUEUE_SEND( pxQueue ); - prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); - - #if ( configUSE_QUEUE_SETS == 1 ) - { - if( pxQueue->pxQueueSetContainer != NULL ) - { - if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE ) - { - /* The queue is a member of a queue set, and posting - to the queue set caused a higher priority task to - unblock. A context switch is required. */ - portYIELD_WITHIN_API(); - } - } - else - { - /* If there was a task waiting for data to arrive on the - queue then unblock it now. */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) - { - /* The unblocked task has a priority higher than - our own so yield immediately. Yes it is ok to - do this from within the critical section - the - kernel takes care of that. */ - portYIELD_WITHIN_API(); - } - } - } - } - #else /* configUSE_QUEUE_SETS */ - { - /* If there was a task waiting for data to arrive on the - queue then unblock it now. */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) - { - /* The unblocked task has a priority higher than - our own so yield immediately. Yes it is ok to do - this from within the critical section - the kernel - takes care of that. */ - portYIELD_WITHIN_API(); - } - } - } - #endif /* configUSE_QUEUE_SETS */ - - taskEXIT_CRITICAL(); - - /* Return to the original privilege level before exiting the - function. */ - return pdPASS; - } - else - { - if( xTicksToWait == ( portTickType ) 0 ) - { - /* The queue was full and no block time is specified (or - the block time has expired) so leave now. */ - taskEXIT_CRITICAL(); - - /* Return to the original privilege level before exiting - the function. */ - traceQUEUE_SEND_FAILED( pxQueue ); - return errQUEUE_FULL; - } - else if( xEntryTimeSet == pdFALSE ) - { - /* The queue was full and a block time was specified so - configure the timeout structure. */ - vTaskSetTimeOutState( &xTimeOut ); - xEntryTimeSet = pdTRUE; - } - else - { - /* Entry time was already set. */ - } - } - } - taskEXIT_CRITICAL(); - - /* Interrupts and other tasks can send to and receive from the queue - now the critical section has been exited. */ - - vTaskSuspendAll(); - prvLockQueue( pxQueue ); - - /* Update the timeout state to see if it has expired yet. */ - if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) - { - if( prvIsQueueFull( pxQueue ) != pdFALSE ) - { - traceBLOCKING_ON_QUEUE_SEND( pxQueue ); - vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); - - /* Unlocking the queue means queue events can effect the - event list. It is possible that interrupts occurring now - remove this task from the event list again - but as the - scheduler is suspended the task will go onto the pending - ready last instead of the actual ready list. */ - prvUnlockQueue( pxQueue ); - - /* Resuming the scheduler will move tasks from the pending - ready list into the ready list - so it is feasible that this - task is already in a ready list before it yields - in which - case the yield will not cause a context switch unless there - is also a higher priority task in the pending ready list. */ - if( xTaskResumeAll() == pdFALSE ) - { - portYIELD_WITHIN_API(); - } - } - else - { - /* Try again. */ - prvUnlockQueue( pxQueue ); - ( void ) xTaskResumeAll(); - } - } - else - { - /* The timeout has expired. */ - prvUnlockQueue( pxQueue ); - ( void ) xTaskResumeAll(); - - /* Return to the original privilege level before exiting the - function. */ - traceQUEUE_SEND_FAILED( pxQueue ); - return errQUEUE_FULL; - } - } -} -/*-----------------------------------------------------------*/ - -#if ( configUSE_ALTERNATIVE_API == 1 ) - - signed portBASE_TYPE ICACHE_FLASH_ATTR - xQueueAltGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) - { - signed portBASE_TYPE xEntryTimeSet = pdFALSE; - xTimeOutType xTimeOut; - xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - configASSERT( pxQueue ); - configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - for( ;; ) - { - taskENTER_CRITICAL(); - { - /* Is there room on the queue now? To be running we must be - the highest priority task wanting to access the queue. */ - if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) - { - traceQUEUE_SEND( pxQueue ); - prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); - - /* If there was a task waiting for data to arrive on the - queue then unblock it now. */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) - { - /* The unblocked task has a priority higher than - our own so yield immediately. */ - portYIELD_WITHIN_API(); - } - } - - taskEXIT_CRITICAL(); - return pdPASS; - } - else - { - if( xTicksToWait == ( portTickType ) 0 ) - { - taskEXIT_CRITICAL(); - return errQUEUE_FULL; - } - else if( xEntryTimeSet == pdFALSE ) - { - vTaskSetTimeOutState( &xTimeOut ); - xEntryTimeSet = pdTRUE; - } - } - } - taskEXIT_CRITICAL(); - - taskENTER_CRITICAL(); - { - if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) - { - if( prvIsQueueFull( pxQueue ) != pdFALSE ) - { - traceBLOCKING_ON_QUEUE_SEND( pxQueue ); - vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); - portYIELD_WITHIN_API(); - } - } - else - { - taskEXIT_CRITICAL(); - traceQUEUE_SEND_FAILED( pxQueue ); - return errQUEUE_FULL; - } - } - taskEXIT_CRITICAL(); - } - } - -#endif /* configUSE_ALTERNATIVE_API */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_ALTERNATIVE_API == 1 ) - - signed portBASE_TYPE ICACHE_FLASH_ATTR - xQueueAltGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) - { - signed portBASE_TYPE xEntryTimeSet = pdFALSE; - xTimeOutType xTimeOut; - signed char *pcOriginalReadPosition; - xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - configASSERT( pxQueue ); - configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - for( ;; ) - { - taskENTER_CRITICAL(); - { - if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) - { - /* Remember our read position in case we are just peeking. */ - pcOriginalReadPosition = pxQueue->u.pcReadFrom; - - prvCopyDataFromQueue( pxQueue, pvBuffer ); - - if( xJustPeeking == pdFALSE ) - { - traceQUEUE_RECEIVE( pxQueue ); - - /* Data is actually being removed (not just peeked). */ - --( pxQueue->uxMessagesWaiting ); - - #if ( configUSE_MUTEXES == 1 ) - { - if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) - { - /* Record the information required to implement - priority inheritance should it become necessary. */ - pxQueue->pxMutexHolder = ( signed char * ) xTaskGetCurrentTaskHandle(); - } - } - #endif - - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) - { - portYIELD_WITHIN_API(); - } - } - } - else - { - traceQUEUE_PEEK( pxQueue ); - - /* We are not removing the data, so reset our read - pointer. */ - pxQueue->u.pcReadFrom = pcOriginalReadPosition; - - /* The data is being left in the queue, so see if there are - any other tasks waiting for the data. */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - /* Tasks that are removed from the event list will get added to - the pending ready list as the scheduler is still suspended. */ - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority than this task. */ - portYIELD_WITHIN_API(); - } - } - - } - - taskEXIT_CRITICAL(); - return pdPASS; - } - else - { - if( xTicksToWait == ( portTickType ) 0 ) - { - taskEXIT_CRITICAL(); - traceQUEUE_RECEIVE_FAILED( pxQueue ); - return errQUEUE_EMPTY; - } - else if( xEntryTimeSet == pdFALSE ) - { - vTaskSetTimeOutState( &xTimeOut ); - xEntryTimeSet = pdTRUE; - } - } - } - taskEXIT_CRITICAL(); - - taskENTER_CRITICAL(); - { - if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) - { - if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) - { - traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); - - #if ( configUSE_MUTEXES == 1 ) - { - if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) - { - portENTER_CRITICAL(); - { - vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder ); - } - portEXIT_CRITICAL(); - } - } - #endif - - vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); - portYIELD_WITHIN_API(); - } - } - else - { - taskEXIT_CRITICAL(); - traceQUEUE_RECEIVE_FAILED( pxQueue ); - return errQUEUE_EMPTY; - } - } - taskEXIT_CRITICAL(); - } - } - - -#endif /* configUSE_ALTERNATIVE_API */ -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE ICACHE_FLASH_ATTR -xQueueGenericSendFromISR( xQueueHandle xQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) -{ -signed portBASE_TYPE xReturn; -unsigned portBASE_TYPE uxSavedInterruptStatus; -xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - configASSERT( pxQueue ); - configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); - - /* RTOS ports that support interrupt nesting have the concept of a maximum - system call (or maximum API call) interrupt priority. Interrupts that are - above the maximum system call priority are keep permanently enabled, even - when the RTOS kernel is in a critical section, but cannot make any calls to - FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h - then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion - failure if a FreeRTOS API function is called from an interrupt that has been - assigned a priority above the configured maximum system call priority. - Only FreeRTOS functions that end in FromISR can be called from interrupts - that have been assigned a priority at or (logically) below the maximum - system call interrupt priority. FreeRTOS maintains a separate interrupt - safe API to ensure interrupt entry is as fast and as simple as possible. - More information (albeit Cortex-M specific) is provided on the following - link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ - portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - - /* Similar to xQueueGenericSend, except we don't block if there is no room - in the queue. Also we don't directly wake a task that was blocked on a - queue read, instead we return a flag to say whether a context switch is - required or not (i.e. has a task with a higher priority than us been woken - by this post). */ -// uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - portSET_INTERRUPT_MASK_FROM_ISR(); - - { - if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) - { - traceQUEUE_SEND_FROM_ISR( pxQueue ); - - prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); - - /* If the queue is locked we do not alter the event list. This will - be done when the queue is unlocked later. */ - if( pxQueue->xTxLock == queueUNLOCKED ) - { - #if ( configUSE_QUEUE_SETS == 1 ) - { - if( pxQueue->pxQueueSetContainer != NULL ) - { - if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE ) - { - /* The queue is a member of a queue set, and posting - to the queue set caused a higher priority task to - unblock. A context switch is required. */ - if( pxHigherPriorityTaskWoken != NULL ) - { - *pxHigherPriorityTaskWoken = pdTRUE; - } - } - } - else - { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority so record that a - context switch is required. */ - if( pxHigherPriorityTaskWoken != NULL ) - { - *pxHigherPriorityTaskWoken = pdTRUE; - } - } - } - } - } - #else /* configUSE_QUEUE_SETS */ - { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority so record that a - context switch is required. */ - if( pxHigherPriorityTaskWoken != NULL ) - { - *pxHigherPriorityTaskWoken = pdTRUE; - } - } - } - } - #endif /* configUSE_QUEUE_SETS */ - } - else - { - /* Increment the lock count so the task that unlocks the queue - knows that data was posted while it was locked. */ - ++( pxQueue->xTxLock ); - } - - xReturn = pdPASS; - } - else - { - traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); - xReturn = errQUEUE_FULL; - } - } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE ICACHE_FLASH_ATTR -xQueueGenericReceive( xQueueHandle xQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) -{ -signed portBASE_TYPE xEntryTimeSet = pdFALSE; -xTimeOutType xTimeOut; -signed char *pcOriginalReadPosition; -xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - configASSERT( pxQueue ); - configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - /* This function relaxes the coding standard somewhat to allow return - statements within the function itself. This is done in the interest - of execution time efficiency. */ - - for( ;; ) - { - taskENTER_CRITICAL(); - { - /* Is there data in the queue now? To be running we must be - the highest priority task wanting to access the queue. */ - if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) - { - /* Remember the read position in case the queue is only being - peeked. */ - pcOriginalReadPosition = pxQueue->u.pcReadFrom; - - prvCopyDataFromQueue( pxQueue, pvBuffer ); - - if( xJustPeeking == pdFALSE ) - { - traceQUEUE_RECEIVE( pxQueue ); - - /* Actually removing data, not just peeking. */ - --( pxQueue->uxMessagesWaiting ); - - #if ( configUSE_MUTEXES == 1 ) - { - if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) - { - /* Record the information required to implement - priority inheritance should it become necessary. */ - pxQueue->pxMutexHolder = ( signed char * ) xTaskGetCurrentTaskHandle(); /*lint !e961 Cast is not redundant as xTaskHandle is a typedef. */ - } - } - #endif - - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) - { - portYIELD_WITHIN_API(); - } - } - } - else - { - traceQUEUE_PEEK( pxQueue ); - - /* The data is not being removed, so reset the read - pointer. */ - pxQueue->u.pcReadFrom = pcOriginalReadPosition; - - /* The data is being left in the queue, so see if there are - any other tasks waiting for the data. */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - /* Tasks that are removed from the event list will get added to - the pending ready list as the scheduler is still suspended. */ - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority than this task. */ - portYIELD_WITHIN_API(); - } - } - } - - taskEXIT_CRITICAL(); - return pdPASS; - } - else - { - if( xTicksToWait == ( portTickType ) 0 ) - { - /* The queue was empty and no block time is specified (or - the block time has expired) so leave now. */ - taskEXIT_CRITICAL(); - traceQUEUE_RECEIVE_FAILED( pxQueue ); - return errQUEUE_EMPTY; - } - else if( xEntryTimeSet == pdFALSE ) - { - /* The queue was empty and a block time was specified so - configure the timeout structure. */ - vTaskSetTimeOutState( &xTimeOut ); - xEntryTimeSet = pdTRUE; - } - else - { - /* Entry time was already set. */ - } - } - } - taskEXIT_CRITICAL(); - - /* Interrupts and other tasks can send to and receive from the queue - now the critical section has been exited. */ - - vTaskSuspendAll(); - prvLockQueue( pxQueue ); - - /* Update the timeout state to see if it has expired yet. */ - if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) - { - if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) - { - traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); - - #if ( configUSE_MUTEXES == 1 ) - { - if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) - { - portENTER_CRITICAL(); - { - vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder ); - } - portEXIT_CRITICAL(); - } - } - #endif - - vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); - prvUnlockQueue( pxQueue ); - if( xTaskResumeAll() == pdFALSE ) - { - portYIELD_WITHIN_API(); - } - } - else - { - /* Try again. */ - prvUnlockQueue( pxQueue ); - ( void ) xTaskResumeAll(); - } - } - else - { - prvUnlockQueue( pxQueue ); - ( void ) xTaskResumeAll(); - traceQUEUE_RECEIVE_FAILED( pxQueue ); - return errQUEUE_EMPTY; - } - } -} -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE ICACHE_FLASH_ATTR -xQueueReceiveFromISR( xQueueHandle xQueue, const void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken ) -{ -signed portBASE_TYPE xReturn; -unsigned portBASE_TYPE uxSavedInterruptStatus; -xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - configASSERT( pxQueue ); - configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - /* RTOS ports that support interrupt nesting have the concept of a maximum - system call (or maximum API call) interrupt priority. Interrupts that are - above the maximum system call priority are keep permanently enabled, even - when the RTOS kernel is in a critical section, but cannot make any calls to - FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h - then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion - failure if a FreeRTOS API function is called from an interrupt that has been - assigned a priority above the configured maximum system call priority. - Only FreeRTOS functions that end in FromISR can be called from interrupts - that have been assigned a priority at or (logically) below the maximum - system call interrupt priority. FreeRTOS maintains a separate interrupt - safe API to ensure interrupt entry is as fast and as simple as possible. - More information (albeit Cortex-M specific) is provided on the following - link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ - portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - -// uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - portSET_INTERRUPT_MASK_FROM_ISR(); - - { - /* Cannot block in an ISR, so check there is data available. */ - if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) - { - traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); - - prvCopyDataFromQueue( pxQueue, pvBuffer ); - --( pxQueue->uxMessagesWaiting ); - - /* If the queue is locked the event list will not be modified. - Instead update the lock count so the task that unlocks the queue - will know that an ISR has removed data while the queue was - locked. */ - if( pxQueue->xRxLock == queueUNLOCKED ) - { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) - { - /* The task waiting has a higher priority than us so - force a context switch. */ - if( pxHigherPriorityTaskWoken != NULL ) - { - *pxHigherPriorityTaskWoken = pdTRUE; - } - } - } - } - else - { - /* Increment the lock count so the task that unlocks the queue - knows that data was removed while it was locked. */ - ++( pxQueue->xRxLock ); - } - - xReturn = pdPASS; - } - else - { - xReturn = pdFAIL; - traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); - } - } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE ICACHE_FLASH_ATTR -xQueuePeekFromISR( xQueueHandle xQueue, const void * const pvBuffer ) -{ -signed portBASE_TYPE xReturn; -unsigned portBASE_TYPE uxSavedInterruptStatus; -signed char *pcOriginalReadPosition; -xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - configASSERT( pxQueue ); - configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); - - /* RTOS ports that support interrupt nesting have the concept of a maximum - system call (or maximum API call) interrupt priority. Interrupts that are - above the maximum system call priority are keep permanently enabled, even - when the RTOS kernel is in a critical section, but cannot make any calls to - FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h - then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion - failure if a FreeRTOS API function is called from an interrupt that has been - assigned a priority above the configured maximum system call priority. - Only FreeRTOS functions that end in FromISR can be called from interrupts - that have been assigned a priority at or (logically) below the maximum - system call interrupt priority. FreeRTOS maintains a separate interrupt - safe API to ensure interrupt entry is as fast and as simple as possible. - More information (albeit Cortex-M specific) is provided on the following - link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ - portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - -// uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - portSET_INTERRUPT_MASK_FROM_ISR(); - - { - /* Cannot block in an ISR, so check there is data available. */ - if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) - { - traceQUEUE_PEEK_FROM_ISR( pxQueue ); - - /* Remember the read position so it can be reset as nothing is - actually being removed from the queue. */ - pcOriginalReadPosition = pxQueue->u.pcReadFrom; - prvCopyDataFromQueue( pxQueue, pvBuffer ); - pxQueue->u.pcReadFrom = pcOriginalReadPosition; - - xReturn = pdPASS; - } - else - { - xReturn = pdFAIL; - traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); - } - } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -unsigned portBASE_TYPE ICACHE_FLASH_ATTR -uxQueueMessagesWaiting( const xQueueHandle xQueue ) -{ -unsigned portBASE_TYPE uxReturn; - - configASSERT( xQueue ); - - taskENTER_CRITICAL(); - uxReturn = ( ( xQUEUE * ) xQueue )->uxMessagesWaiting; - taskEXIT_CRITICAL(); - - return uxReturn; -} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ -/*-----------------------------------------------------------*/ - -unsigned portBASE_TYPE -uxQueueMessagesWaitingFromISR( const xQueueHandle xQueue ) -{ -unsigned portBASE_TYPE uxReturn; - - configASSERT( xQueue ); - - uxReturn = ( ( xQUEUE * ) xQueue )->uxMessagesWaiting; - - return uxReturn; -} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ -/*-----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vQueueDelete( xQueueHandle xQueue ) -{ -xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - configASSERT( pxQueue ); - - traceQUEUE_DELETE( pxQueue ); - #if ( configQUEUE_REGISTRY_SIZE > 0 ) - { - vQueueUnregisterQueue( pxQueue ); - } - #endif - os_free( pxQueue->pcHead ); - os_free( pxQueue ); -} -/*-----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - unsigned char ICACHE_FLASH_ATTR - ucQueueGetQueueNumber( xQueueHandle xQueue ) - { - return ( ( xQUEUE * ) xQueue )->ucQueueNumber; - } - -#endif /* configUSE_TRACE_FACILITY */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - void ICACHE_FLASH_ATTR - vQueueSetQueueNumber( xQueueHandle xQueue, unsigned char ucQueueNumber ) - { - ( ( xQUEUE * ) xQueue )->ucQueueNumber = ucQueueNumber; - } - -#endif /* configUSE_TRACE_FACILITY */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - unsigned char ICACHE_FLASH_ATTR - ucQueueGetQueueType( xQueueHandle xQueue ) - { - return ( ( xQUEUE * ) xQueue )->ucQueueType; - } - -#endif /* configUSE_TRACE_FACILITY */ -/*-----------------------------------------------------------*/ - -static void -prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) -{ - if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 ) - { - #if ( configUSE_MUTEXES == 1 ) - { - if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) - { - /* The mutex is no longer being held. */ - vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder ); - pxQueue->pxMutexHolder = NULL; - } - } - #endif /* configUSE_MUTEXES */ - } - else if( xPosition == queueSEND_TO_BACK ) - { - ( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. */ - pxQueue->pcWriteTo += pxQueue->uxItemSize; - if( pxQueue->pcWriteTo >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ - { - pxQueue->pcWriteTo = pxQueue->pcHead; - } - } - else - { - ( void ) memcpy( ( void * ) pxQueue->u.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - pxQueue->u.pcReadFrom -= pxQueue->uxItemSize; - if( pxQueue->u.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ - { - pxQueue->u.pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize ); - } - - if( xPosition == queueOVERWRITE ) - { - if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) - { - /* An item is not being added but overwritten, so subtract - one from the recorded number of items in the queue so when - one is added again below the number of recorded items remains - correct. */ - --( pxQueue->uxMessagesWaiting ); - } - } - } - - ++( pxQueue->uxMessagesWaiting ); -} -/*-----------------------------------------------------------*/ - -static void -prvCopyDataFromQueue( xQUEUE * const pxQueue, const void * const pvBuffer ) -{ - if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX ) - { - pxQueue->u.pcReadFrom += pxQueue->uxItemSize; - if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */ - { - pxQueue->u.pcReadFrom = pxQueue->pcHead; - } - ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */ - } -} -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvUnlockQueue( xQUEUE *pxQueue ) -{ - /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ - - /* The lock counts contains the number of extra data items placed or - removed from the queue while the queue was locked. When a queue is - locked items can be added or removed, but the event lists cannot be - updated. */ - taskENTER_CRITICAL(); - { - /* See if data was added to the queue while it was locked. */ - while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED ) - { - /* Data was posted while the queue was locked. Are any tasks - blocked waiting for data to become available? */ - #if ( configUSE_QUEUE_SETS == 1 ) - { - if( pxQueue->pxQueueSetContainer != NULL ) - { - if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE ) - { - /* The queue is a member of a queue set, and posting to - the queue set caused a higher priority task to unblock. - A context switch is required. */ - vTaskMissedYield(); - } - } - else - { - /* Tasks that are removed from the event list will get added to - the pending ready list as the scheduler is still suspended. */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority so record that a - context switch is required. */ - vTaskMissedYield(); - } - } - else - { - break; - } - } - } - #else /* configUSE_QUEUE_SETS */ - { - /* Tasks that are removed from the event list will get added to - the pending ready list as the scheduler is still suspended. */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority so record that a - context switch is required. */ - vTaskMissedYield(); - } - } - else - { - break; - } - } - #endif /* configUSE_QUEUE_SETS */ - - --( pxQueue->xTxLock ); - } - - pxQueue->xTxLock = queueUNLOCKED; - } - taskEXIT_CRITICAL(); - - /* Do the same for the Rx lock. */ - taskENTER_CRITICAL(); - { - while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED ) - { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) - { - vTaskMissedYield(); - } - - --( pxQueue->xRxLock ); - } - else - { - break; - } - } - - pxQueue->xRxLock = queueUNLOCKED; - } - taskEXIT_CRITICAL(); -} -/*-----------------------------------------------------------*/ - -static signed portBASE_TYPE ICACHE_FLASH_ATTR -prvIsQueueEmpty( const xQUEUE *pxQueue ) -{ -signed portBASE_TYPE xReturn; - - taskENTER_CRITICAL(); - { - if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ) - { - xReturn = pdTRUE; - } - else - { - xReturn = pdFALSE; - } - } - taskEXIT_CRITICAL(); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE ICACHE_FLASH_ATTR -xQueueIsQueueEmptyFromISR( const xQueueHandle xQueue ) -{ -signed portBASE_TYPE xReturn; - - configASSERT( xQueue ); - if( ( ( xQUEUE * ) xQueue )->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ) - { - xReturn = pdTRUE; - } - else - { - xReturn = pdFALSE; - } - - return xReturn; -} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ -/*-----------------------------------------------------------*/ - -static signed portBASE_TYPE ICACHE_FLASH_ATTR -prvIsQueueFull( const xQUEUE *pxQueue ) -{ -signed portBASE_TYPE xReturn; - - taskENTER_CRITICAL(); - { - if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) - { - xReturn = pdTRUE; - } - else - { - xReturn = pdFALSE; - } - } - taskEXIT_CRITICAL(); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE ICACHE_FLASH_ATTR -xQueueIsQueueFullFromISR( const xQueueHandle xQueue ) -{ -signed portBASE_TYPE xReturn; - - configASSERT( xQueue ); - if( ( ( xQUEUE * ) xQueue )->uxMessagesWaiting == ( ( xQUEUE * ) xQueue )->uxLength ) - { - xReturn = pdTRUE; - } - else - { - xReturn = pdFALSE; - } - - return xReturn; -} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_CO_ROUTINES == 1 ) - - signed portBASE_TYPE ICACHE_FLASH_ATTR - xQueueCRSend( xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait ) - { - signed portBASE_TYPE xReturn; - xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - /* If the queue is already full we may have to block. A critical section - is required to prevent an interrupt removing something from the queue - between the check to see if the queue is full and blocking on the queue. */ - - //portDISABLE_INTERRUPTS(); -PortDisableInt_NoNest(); - { - if( prvIsQueueFull( pxQueue ) != pdFALSE ) - { - /* The queue is full - do we want to block or just leave without - posting? */ - if( xTicksToWait > ( portTickType ) 0 ) - { - /* As this is called from a coroutine we cannot block directly, but - return indicating that we need to block. */ - vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); - //portENABLE_INTERRUPTS(); -PortEnableInt_NoNest(); - return errQUEUE_BLOCKED; - } - else - { - //portENABLE_INTERRUPTS(); -PortEnableInt_NoNest(); - return errQUEUE_FULL; - } - } - } - //portENABLE_INTERRUPTS(); -PortEnableInt_NoNest(); - - //portDISABLE_INTERRUPTS(); -PortDisableInt_NoNest(); - { - if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) - { - /* There is room in the queue, copy the data into the queue. */ - prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); - xReturn = pdPASS; - - /* Were any co-routines waiting for data to become available? */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - /* In this instance the co-routine could be placed directly - into the ready list as we are within a critical section. - Instead the same pending ready list mechanism is used as if - the event were caused from within an interrupt. */ - if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The co-routine waiting has a higher priority so record - that a yield might be appropriate. */ - xReturn = errQUEUE_YIELD; - } - } - } - else - { - xReturn = errQUEUE_FULL; - } - } - //portENABLE_INTERRUPTS(); -PortEnableInt_NoNest(); - return xReturn; - } - -#endif /* configUSE_CO_ROUTINES */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_CO_ROUTINES == 1 ) - - signed portBASE_TYPE ICACHE_FLASH_ATTR - xQueueCRReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait ) - { - signed portBASE_TYPE xReturn; - xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - /* If the queue is already empty we may have to block. A critical section - is required to prevent an interrupt adding something to the queue - between the check to see if the queue is empty and blocking on the queue. */ - - //portDISABLE_INTERRUPTS(); -PortDisableInt_NoNest(); - { - if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ) - { - /* There are no messages in the queue, do we want to block or just - leave with nothing? */ - if( xTicksToWait > ( portTickType ) 0 ) - { - /* As this is a co-routine we cannot block directly, but return - indicating that we need to block. */ - vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); - //portENABLE_INTERRUPTS(); -PortEnableInt_NoNest(); - return errQUEUE_BLOCKED; - } - else - { - //portENABLE_INTERRUPTS(); -PortEnableInt_NoNest(); - return errQUEUE_FULL; - } - } - } - //portENABLE_INTERRUPTS(); -PortEnableInt_NoNest(); - - //portDISABLE_INTERRUPTS(); -PortDisableInt_NoNest(); - { - if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) - { - /* Data is available from the queue. */ - pxQueue->u.pcReadFrom += pxQueue->uxItemSize; - if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) - { - pxQueue->u.pcReadFrom = pxQueue->pcHead; - } - --( pxQueue->uxMessagesWaiting ); - ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); - - xReturn = pdPASS; - - /* Were any co-routines waiting for space to become available? */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) - { - /* In this instance the co-routine could be placed directly - into the ready list as we are within a critical section. - Instead the same pending ready list mechanism is used as if - the event were caused from within an interrupt. */ - if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) - { - xReturn = errQUEUE_YIELD; - } - } - } - else - { - xReturn = pdFAIL; - } - } - //portENABLE_INTERRUPTS(); -PortEnableInt_NoNest(); - - return xReturn; - } - -#endif /* configUSE_CO_ROUTINES */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_CO_ROUTINES == 1 ) - - signed portBASE_TYPE ICACHE_FLASH_ATTR - xQueueCRSendFromISR( xQueueHandle xQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) - { - xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - /* Cannot block within an ISR so if there is no space on the queue then - exit without doing anything. */ - if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) - { - prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); - - /* We only want to wake one co-routine per ISR, so check that a - co-routine has not already been woken. */ - if( xCoRoutinePreviouslyWoken == pdFALSE ) - { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - return pdTRUE; - } - } - } - } - - return xCoRoutinePreviouslyWoken; - } - -#endif /* configUSE_CO_ROUTINES */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_CO_ROUTINES == 1 ) - - signed portBASE_TYPE ICACHE_FLASH_ATTR - xQueueCRReceiveFromISR( xQueueHandle xQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken ) - { - signed portBASE_TYPE xReturn; - xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - /* We cannot block from an ISR, so check there is data available. If - not then just leave without doing anything. */ - if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) - { - /* Copy the data from the queue. */ - pxQueue->u.pcReadFrom += pxQueue->uxItemSize; - if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) - { - pxQueue->u.pcReadFrom = pxQueue->pcHead; - } - --( pxQueue->uxMessagesWaiting ); - ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); - - if( ( *pxCoRoutineWoken ) == pdFALSE ) - { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) - { - if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) - { - *pxCoRoutineWoken = pdTRUE; - } - } - } - - xReturn = pdPASS; - } - else - { - xReturn = pdFAIL; - } - - return xReturn; - } - -#endif /* configUSE_CO_ROUTINES */ -/*-----------------------------------------------------------*/ - -#if ( configQUEUE_REGISTRY_SIZE > 0 ) - - void ICACHE_FLASH_ATTR - vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) - { - unsigned portBASE_TYPE ux; - - /* See if there is an empty space in the registry. A NULL name denotes - a free slot. */ - for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ ) - { - if( xQueueRegistry[ ux ].pcQueueName == NULL ) - { - /* Store the information on this queue. */ - xQueueRegistry[ ux ].pcQueueName = pcQueueName; - xQueueRegistry[ ux ].xHandle = xQueue; - break; - } - } - } - -#endif /* configQUEUE_REGISTRY_SIZE */ -/*-----------------------------------------------------------*/ - -#if ( configQUEUE_REGISTRY_SIZE > 0 ) - - void ICACHE_FLASH_ATTR - vQueueUnregisterQueue( xQueueHandle xQueue ) - { - unsigned portBASE_TYPE ux; - - /* See if the handle of the queue being unregistered in actually in the - registry. */ - for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ ) - { - if( xQueueRegistry[ ux ].xHandle == xQueue ) - { - /* Set the name to NULL to show that this slot if free again. */ - xQueueRegistry[ ux ].pcQueueName = NULL; - break; - } - } - - } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ - -#endif /* configQUEUE_REGISTRY_SIZE */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_TIMERS == 1 ) - - void ICACHE_FLASH_ATTR - vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait ) - { - xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; - - /* This function should not be called by application code hence the - 'Restricted' in its name. It is not part of the public API. It is - designed for use by kernel code, and has special calling requirements. - It can result in vListInsert() being called on a list that can only - possibly ever have one item in it, so the list will be fast, but even - so it should be called with the scheduler locked and not from a critical - section. */ - - /* Only do anything if there are no messages in the queue. This function - will not actually cause the task to block, just place it on a blocked - list. It will not block until the scheduler is unlocked - at which - time a yield will be performed. If an item is added to the queue while - the queue is locked, and the calling task blocks on the queue, then the - calling task will be immediately unblocked when the queue is unlocked. */ - prvLockQueue( pxQueue ); - if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0U ) - { - /* There is nothing in the queue, block for the specified period. */ - vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); - } - prvUnlockQueue( pxQueue ); - } - -#endif /* configUSE_TIMERS */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_QUEUE_SETS == 1 ) - - xQueueSetHandle ICACHE_FLASH_ATTR - xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength ) - { - xQueueSetHandle pxQueue; - - pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( xQUEUE * ), queueQUEUE_TYPE_SET ); - - return pxQueue; - } - -#endif /* configUSE_QUEUE_SETS */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_QUEUE_SETS == 1 ) - - portBASE_TYPE ICACHE_FLASH_ATTR - xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) - { - portBASE_TYPE xReturn; - - if( ( ( xQUEUE * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) - { - /* Cannot add a queue/semaphore to more than one queue set. */ - xReturn = pdFAIL; - } - else if( ( ( xQUEUE * ) xQueueOrSemaphore )->uxMessagesWaiting != ( unsigned portBASE_TYPE ) 0 ) - { - /* Cannot add a queue/semaphore to a queue set if there are already - items in the queue/semaphore. */ - xReturn = pdFAIL; - } - else - { - taskENTER_CRITICAL(); - { - ( ( xQUEUE * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet; - } - taskEXIT_CRITICAL(); - xReturn = pdPASS; - } - - return xReturn; - } - -#endif /* configUSE_QUEUE_SETS */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_QUEUE_SETS == 1 ) - - portBASE_TYPE ICACHE_FLASH_ATTR - xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) - { - portBASE_TYPE xReturn; - xQUEUE * const pxQueueOrSemaphore = ( xQUEUE * ) xQueueOrSemaphore; - - if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet ) - { - /* The queue was not a member of the set. */ - xReturn = pdFAIL; - } - else if( pxQueueOrSemaphore->uxMessagesWaiting != ( unsigned portBASE_TYPE ) 0 ) - { - /* It is dangerous to remove a queue from a set when the queue is - not empty because the queue set will still hold pending events for - the queue. */ - xReturn = pdFAIL; - } - else - { - taskENTER_CRITICAL(); - { - /* The queue is no longer contained in the set. */ - pxQueueOrSemaphore->pxQueueSetContainer = NULL; - } - taskEXIT_CRITICAL(); - xReturn = pdPASS; - } - - return xReturn; - } /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */ - -#endif /* configUSE_QUEUE_SETS */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_QUEUE_SETS == 1 ) - - xQueueSetMemberHandle ICACHE_FLASH_ATTR - xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) - { - xQueueSetMemberHandle xReturn = NULL; - - ( void ) xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */ - return xReturn; - } - -#endif /* configUSE_QUEUE_SETS */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_QUEUE_SETS == 1 ) - - xQueueSetMemberHandle ICACHE_FLASH_ATTR - xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet ) - { - xQueueSetMemberHandle xReturn = NULL; - - ( void ) xQueueReceiveFromISR( ( xQueueHandle ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */ - return xReturn; - } - -#endif /* configUSE_QUEUE_SETS */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_QUEUE_SETS == 1 ) - - static portBASE_TYPE ICACHE_FLASH_ATTR - prvNotifyQueueSetContainer( const xQUEUE * const pxQueue, portBASE_TYPE xCopyPosition ) - { - xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer; - portBASE_TYPE xReturn = pdFALSE; - - configASSERT( pxQueueSetContainer ); - configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ); - - if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ) - { - traceQUEUE_SEND( pxQueueSetContainer ); - /* The data copies is the handle of the queue that contains data. */ - prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition ); - if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The task waiting has a higher priority */ - xReturn = pdTRUE; - } - } - } - - return xReturn; - } - -#endif /* configUSE_QUEUE_SETS */ - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" + +#if ( configUSE_CO_ROUTINES == 1 ) + #include "freertos/croutine.h" +#endif + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + + +/* Constants used with the cRxLock and xTxLock structure members. */ +#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 ) +#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 ) + +/* When the xQUEUE structure is used to represent a base queue its pcHead and +pcTail members are used as pointers into the queue storage area. When the +xQUEUE structure is used to represent a mutex pcHead and pcTail pointers are +not necessary, and the pcHead pointer is set to NULL to indicate that the +pcTail pointer actually points to the mutex holder (if any). Map alternative +names to the pcHead and pcTail structure members to ensure the readability of +the code is maintained despite this dual use of two structure members. An +alternative implementation would be to use a union, but use of a union is +against the coding standard (although an exception to the standard has been +permitted where the dual use also significantly changes the type of the +structure member). */ +#define pxMutexHolder pcTail +#define uxQueueType pcHead +#define queueQUEUE_IS_MUTEX NULL + +/* Semaphores do not actually store or copy data, so have an item size of +zero. */ +#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 ) +#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0U ) + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; +#endif + + +/* + * Definition of the queue used by the scheduler. + * Items are queued by copy, not reference. + */ +typedef struct QueueDefinition +{ + signed char *pcHead; /*< Points to the beginning of the queue storage area. */ + signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + + signed char *pcWriteTo; /*< Points to the free next place in the storage area. */ + + union /* Use of a union is an exception to the coding standard to ensure two mutually exclusive structure members don't appear simultaneously (wasting RAM). */ + { + signed char *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */ + unsigned portBASE_TYPE uxRecursiveCallCount;/*< Maintains a count of the numebr of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ + } u; + + xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + + volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */ + unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */ + + volatile signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + volatile signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + + #if ( configUSE_TRACE_FACILITY == 1 ) + unsigned char ucQueueNumber; + unsigned char ucQueueType; + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + struct QueueDefinition *pxQueueSetContainer; + #endif + +} xQUEUE; +/*-----------------------------------------------------------*/ + +/* + * The queue registry is just a means for kernel aware debuggers to locate + * queue structures. It has no other purpose so is an optional component. + */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + /* The type stored within the queue registry array. This allows a name + to be assigned to each queue making kernel aware debugging a little + more user friendly. */ + typedef struct QUEUE_REGISTRY_ITEM + { + signed char *pcQueueName; + xQueueHandle xHandle; + } xQueueRegistryItem; + + /* The queue registry is simply an array of xQueueRegistryItem structures. + The pcQueueName member of a structure being NULL is indicative of the + array position being vacant. */ + xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; + +#endif /* configQUEUE_REGISTRY_SIZE */ + +/* + * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not + * prevent an ISR from adding or removing items to the queue, but does prevent + * an ISR from removing tasks from the queue event lists. If an ISR finds a + * queue is locked it will instead increment the appropriate queue lock count + * to indicate that a task may require unblocking. When the queue in unlocked + * these lock counts are inspected, and the appropriate action taken. + */ +static void prvUnlockQueue( xQUEUE *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any data in a queue. + * + * @return pdTRUE if the queue contains no items, otherwise pdFALSE. + */ +static signed portBASE_TYPE prvIsQueueEmpty( const xQUEUE *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any space in a queue. + * + * @return pdTRUE if there is no space, otherwise pdFALSE; + */ +static signed portBASE_TYPE prvIsQueueFull( const xQUEUE *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Copies an item into the queue, either at the front of the queue or the + * back of the queue. + */ +static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION; + +/* + * Copies an item out of a queue. + */ +static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void * const pvBuffer ) PRIVILEGED_FUNCTION; + +#if ( configUSE_QUEUE_SETS == 1 ) + /* + * Checks to see if a queue is a member of a queue set, and if so, notifies + * the queue set that the queue contains data. + */ + static portBASE_TYPE prvNotifyQueueSetContainer( const xQUEUE * const pxQueue, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION; +#endif + +/*-----------------------------------------------------------*/ + +/* + * Macro to mark a queue as locked. Locking a queue prevents an ISR from + * accessing the queue event lists. + */ +#define prvLockQueue( pxQueue ) \ + taskENTER_CRITICAL(); \ + { \ + if( ( pxQueue )->xRxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \ + } \ + if( ( pxQueue )->xTxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \ + } \ + } \ + taskEXIT_CRITICAL() +/*-----------------------------------------------------------*/ + +portBASE_TYPE ICACHE_FLASH_ATTR +xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue ) +{ +xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); + pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U; + pxQueue->pcWriteTo = pxQueue->pcHead; + pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize ); + pxQueue->xRxLock = queueUNLOCKED; + pxQueue->xTxLock = queueUNLOCKED; + + if( xNewQueue == pdFALSE ) + { + /* If there are tasks blocked waiting to read from the queue, then + the tasks will remain blocked as after this function exits the queue + will still be empty. If there are tasks blocked waiting to write to + the queue, then one should be unblocked as after this function exits + it will be possible to write to it. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) + { + portYIELD_WITHIN_API(); + } + } + } + else + { + /* Ensure the event queues start in the correct state. */ + vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); + } + } + taskEXIT_CRITICAL(); + + /* A value is returned for calling semantic consistency with previous + versions. */ + return pdPASS; +} +/*-----------------------------------------------------------*/ + +xQueueHandle ICACHE_FLASH_ATTR +xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType ) +{ +xQUEUE *pxNewQueue; +size_t xQueueSizeInBytes; +xQueueHandle xReturn = NULL; + + /* Remove compiler warnings about unused parameters should + configUSE_TRACE_FACILITY not be set to 1. */ + ( void ) ucQueueType; + + /* Allocate the new queue structure. */ + if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 ) + { + pxNewQueue = ( xQUEUE * ) os_malloc( sizeof( xQUEUE ) ); + if( pxNewQueue != NULL ) + { + /* Create the list of pointers to queue items. The queue is one byte + longer than asked for to make wrap checking easier/faster. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + pxNewQueue->pcHead = ( signed char * ) os_malloc( xQueueSizeInBytes ); + if( pxNewQueue->pcHead != NULL ) + { + /* Initialise the queue members as described above where the + queue type is defined. */ + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif /* configUSE_TRACE_FACILITY */ + + #if( configUSE_QUEUE_SETS == 1 ) + { + pxNewQueue->pxQueueSetContainer = NULL; + } + #endif /* configUSE_QUEUE_SETS */ + + traceQUEUE_CREATE( pxNewQueue ); + xReturn = pxNewQueue; + } + else + { + traceQUEUE_CREATE_FAILED( ucQueueType ); + os_free( pxNewQueue ); + } + } + } + + configASSERT( xReturn ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + xQueueHandle ICACHE_FLASH_ATTR + xQueueCreateMutex( unsigned char ucQueueType ) + { + xQUEUE *pxNewQueue; + + /* Prevent compiler warnings about unused parameters if + configUSE_TRACE_FACILITY does not equal 1. */ + ( void ) ucQueueType; + + /* Allocate the new queue structure. */ + pxNewQueue = ( xQUEUE * ) os_malloc( sizeof( xQUEUE ) ); + if( pxNewQueue != NULL ) + { + /* Information required for priority inheritance. */ + pxNewQueue->pxMutexHolder = NULL; + pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; + + /* Queues used as a mutex no data is actually copied into or out + of the queue. */ + pxNewQueue->pcWriteTo = NULL; + pxNewQueue->u.pcReadFrom = NULL; + + /* Each mutex has a length of 1 (like a binary semaphore) and + an item size of 0 as nothing is actually copied into or out + of the mutex. */ + pxNewQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U; + pxNewQueue->uxLength = ( unsigned portBASE_TYPE ) 1U; + pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U; + pxNewQueue->xRxLock = queueUNLOCKED; + pxNewQueue->xTxLock = queueUNLOCKED; + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + { + pxNewQueue->pxQueueSetContainer = NULL; + } + #endif + + /* Ensure the event queues start with the correct state. */ + vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); + + traceCREATE_MUTEX( pxNewQueue ); + + /* Start with the semaphore in the expected state. */ + ( void ) xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK ); + } + else + { + traceCREATE_MUTEX_FAILED(); + } + + configASSERT( pxNewQueue ); + return pxNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + void* ICACHE_FLASH_ATTR + xQueueGetMutexHolder( xQueueHandle xSemaphore ) + { + void *pxReturn; + + /* This function is called by xSemaphoreGetMutexHolder(), and should not + be called directly. Note: This is is a good way of determining if the + calling task is the mutex holder, but not a good way of determining the + identity of the mutex holder, as the holder may change between the + following critical section exiting and the function returning. */ + taskENTER_CRITICAL(); + { + if( ( ( xQUEUE * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = ( void * ) ( ( xQUEUE * ) xSemaphore )->pxMutexHolder; + } + else + { + pxReturn = NULL; + } + } + taskEXIT_CRITICAL(); + + return pxReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + portBASE_TYPE ICACHE_FLASH_ATTR + xQueueGiveMutexRecursive( xQueueHandle xMutex ) + { + portBASE_TYPE xReturn; + xQUEUE * const pxMutex = ( xQUEUE * ) xMutex; + + configASSERT( pxMutex ); + + /* If this is the task that holds the mutex then pxMutexHolder will not + change outside of this task. If this task does not hold the mutex then + pxMutexHolder can never coincidentally equal the tasks handle, and as + this is the only condition we are interested in it does not matter if + pxMutexHolder is accessed simultaneously by another task. Therefore no + mutual exclusion is required to test the pxMutexHolder variable. */ + if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Not a redundant cast as xTaskHandle is a typedef. */ + { + traceGIVE_MUTEX_RECURSIVE( pxMutex ); + + /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to + the task handle, therefore no underflow check is required. Also, + uxRecursiveCallCount is only modified by the mutex holder, and as + there can only be one, no mutual exclusion is required to modify the + uxRecursiveCallCount member. */ + ( pxMutex->u.uxRecursiveCallCount )--; + + /* Have we unwound the call count? */ + if( pxMutex->u.uxRecursiveCallCount == ( unsigned portBASE_TYPE ) 0 ) + { + /* Return the mutex. This will automatically unblock any other + task that might be waiting to access the mutex. */ + ( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); + } + + xReturn = pdPASS; + } + else + { + /* We cannot give the mutex because we are not the holder. */ + xReturn = pdFAIL; + + traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + portBASE_TYPE ICACHE_FLASH_ATTR + xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime ) + { + portBASE_TYPE xReturn; + xQUEUE * const pxMutex = ( xQUEUE * ) xMutex; + + configASSERT( pxMutex ); + + /* Comments regarding mutual exclusion as per those within + xQueueGiveMutexRecursive(). */ + + traceTAKE_MUTEX_RECURSIVE( pxMutex ); + + if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Cast is not redundant as xTaskHandle is a typedef. */ + { + ( pxMutex->u.uxRecursiveCallCount )++; + xReturn = pdPASS; + } + else + { + xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE ); + + /* pdPASS will only be returned if we successfully obtained the mutex, + we may have blocked to reach here. */ + if( xReturn == pdPASS ) + { + ( pxMutex->u.uxRecursiveCallCount )++; + } + else + { + traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_COUNTING_SEMAPHORES == 1 ) + + xQueueHandle ICACHE_FLASH_ATTR + xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount ) + { + xQueueHandle xHandle; + + xHandle = xQueueGenericCreate( uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( xQUEUE * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + configASSERT( xHandle ); + return xHandle; + } + +#endif /* configUSE_COUNTING_SEMAPHORES */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE ICACHE_FLASH_ATTR +xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) +{ +signed portBASE_TYPE xEntryTimeSet = pdFALSE; +xTimeOutType xTimeOut; +xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? The running task must be + the highest priority task wanting to access the queue. If + the head item in the queue is to be overwritten then it does + not matter if the queue is full. */ + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + traceQUEUE_SEND( pxQueue ); + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + portYIELD_WITHIN_API(); + } + } + else + { + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to + do this from within the critical section - the + kernel takes care of that. */ + portYIELD_WITHIN_API(); + } + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to do + this from within the critical section - the kernel + takes care of that. */ + portYIELD_WITHIN_API(); + } + } + } + #endif /* configUSE_QUEUE_SETS */ + + taskEXIT_CRITICAL(); + + /* Return to the original privilege level before exiting the + function. */ + return pdPASS; + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + { + /* The queue was full and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + + /* Return to the original privilege level before exiting + the function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was full and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + + /* Unlocking the queue means queue events can effect the + event list. It is possible that interrupts occurring now + remove this task from the event list again - but as the + scheduler is suspended the task will go onto the pending + ready last instead of the actual ready list. */ + prvUnlockQueue( pxQueue ); + + /* Resuming the scheduler will move tasks from the pending + ready list into the ready list - so it is feasible that this + task is already in a ready list before it yields - in which + case the yield will not cause a context switch unless there + is also a higher priority task in the pending ready list. */ + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + /* Return to the original privilege level before exiting the + function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_ALTERNATIVE_API == 1 ) + + signed portBASE_TYPE ICACHE_FLASH_ATTR + xQueueAltGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition ) + { + signed portBASE_TYPE xEntryTimeSet = pdFALSE; + xTimeOutType xTimeOut; + xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + traceQUEUE_SEND( pxQueue ); + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. */ + portYIELD_WITHIN_API(); + } + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + { + taskEXIT_CRITICAL(); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + portYIELD_WITHIN_API(); + } + } + else + { + taskEXIT_CRITICAL(); + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } + taskEXIT_CRITICAL(); + } + } + +#endif /* configUSE_ALTERNATIVE_API */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_ALTERNATIVE_API == 1 ) + + signed portBASE_TYPE ICACHE_FLASH_ATTR + xQueueAltGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) + { + signed portBASE_TYPE xEntryTimeSet = pdFALSE; + xTimeOutType xTimeOut; + signed char *pcOriginalReadPosition; + xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + for( ;; ) + { + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + /* Remember our read position in case we are just peeking. */ + pcOriginalReadPosition = pxQueue->u.pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + + if( xJustPeeking == pdFALSE ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* Data is actually being removed (not just peeked). */ + --( pxQueue->uxMessagesWaiting ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->pxMutexHolder = ( signed char * ) xTaskGetCurrentTaskHandle(); + } + } + #endif + + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) + { + portYIELD_WITHIN_API(); + } + } + } + else + { + traceQUEUE_PEEK( pxQueue ); + + /* We are not removing the data, so reset our read + pointer. */ + pxQueue->u.pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + portYIELD_WITHIN_API(); + } + } + + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + { + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + portENTER_CRITICAL(); + { + vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder ); + } + portEXIT_CRITICAL(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + portYIELD_WITHIN_API(); + } + } + else + { + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + } + taskEXIT_CRITICAL(); + } + } + + +#endif /* configUSE_ALTERNATIVE_API */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE ICACHE_FLASH_ATTR +xQueueGenericSendFromISR( xQueueHandle xQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition ) +{ +signed portBASE_TYPE xReturn; +unsigned portBASE_TYPE uxSavedInterruptStatus; +xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are keep permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + /* Similar to xQueueGenericSend, except we don't block if there is no room + in the queue. Also we don't directly wake a task that was blocked on a + queue read, instead we return a flag to say whether a context switch is + required or not (i.e. has a task with a higher priority than us been woken + by this post). */ +// uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + portSET_INTERRUPT_MASK_FROM_ISR(); + + { + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* If the queue is locked we do not alter the event list. This will + be done when the queue is unlocked later. */ + if( pxQueue->xTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + } + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + } + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + ++( pxQueue->xTxLock ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE ICACHE_FLASH_ATTR +xQueueGenericReceive( xQueueHandle xQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking ) +{ +signed portBASE_TYPE xEntryTimeSet = pdFALSE; +xTimeOutType xTimeOut; +signed char *pcOriginalReadPosition; +xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there data in the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + /* Remember the read position in case the queue is only being + peeked. */ + pcOriginalReadPosition = pxQueue->u.pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + + if( xJustPeeking == pdFALSE ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* Actually removing data, not just peeking. */ + --( pxQueue->uxMessagesWaiting ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->pxMutexHolder = ( signed char * ) xTaskGetCurrentTaskHandle(); /*lint !e961 Cast is not redundant as xTaskHandle is a typedef. */ + } + } + #endif + + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) + { + portYIELD_WITHIN_API(); + } + } + } + else + { + traceQUEUE_PEEK( pxQueue ); + + /* The data is not being removed, so reset the read + pointer. */ + pxQueue->u.pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + portYIELD_WITHIN_API(); + } + } + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( portTickType ) 0 ) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + portENTER_CRITICAL(); + { + vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder ); + } + portEXIT_CRITICAL(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + } +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE ICACHE_FLASH_ATTR +xQueueReceiveFromISR( xQueueHandle xQueue, const void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken ) +{ +signed portBASE_TYPE xReturn; +unsigned portBASE_TYPE uxSavedInterruptStatus; +xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are keep permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + +// uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + portSET_INTERRUPT_MASK_FROM_ISR(); + + { + /* Cannot block in an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + --( pxQueue->uxMessagesWaiting ); + + /* If the queue is locked the event list will not be modified. + Instead update the lock count so the task that unlocks the queue + will know that an ISR has removed data while the queue was + locked. */ + if( pxQueue->xRxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than us so + force a context switch. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + } + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was removed while it was locked. */ + ++( pxQueue->xRxLock ); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE ICACHE_FLASH_ATTR +xQueuePeekFromISR( xQueueHandle xQueue, const void * const pvBuffer ) +{ +signed portBASE_TYPE xReturn; +unsigned portBASE_TYPE uxSavedInterruptStatus; +signed char *pcOriginalReadPosition; +xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are keep permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + +// uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + portSET_INTERRUPT_MASK_FROM_ISR(); + + { + /* Cannot block in an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + traceQUEUE_PEEK_FROM_ISR( pxQueue ); + + /* Remember the read position so it can be reset as nothing is + actually being removed from the queue. */ + pcOriginalReadPosition = pxQueue->u.pcReadFrom; + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->u.pcReadFrom = pcOriginalReadPosition; + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE ICACHE_FLASH_ATTR +uxQueueMessagesWaiting( const xQueueHandle xQueue ) +{ +unsigned portBASE_TYPE uxReturn; + + configASSERT( xQueue ); + + taskENTER_CRITICAL(); + uxReturn = ( ( xQUEUE * ) xQueue )->uxMessagesWaiting; + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE +uxQueueMessagesWaitingFromISR( const xQueueHandle xQueue ) +{ +unsigned portBASE_TYPE uxReturn; + + configASSERT( xQueue ); + + uxReturn = ( ( xQUEUE * ) xQueue )->uxMessagesWaiting; + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vQueueDelete( xQueueHandle xQueue ) +{ +xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + configASSERT( pxQueue ); + + traceQUEUE_DELETE( pxQueue ); + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + vQueueUnregisterQueue( pxQueue ); + } + #endif + os_free( pxQueue->pcHead ); + os_free( pxQueue ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + unsigned char ICACHE_FLASH_ATTR + ucQueueGetQueueNumber( xQueueHandle xQueue ) + { + return ( ( xQUEUE * ) xQueue )->ucQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void ICACHE_FLASH_ATTR + vQueueSetQueueNumber( xQueueHandle xQueue, unsigned char ucQueueNumber ) + { + ( ( xQUEUE * ) xQueue )->ucQueueNumber = ucQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + unsigned char ICACHE_FLASH_ATTR + ucQueueGetQueueType( xQueueHandle xQueue ) + { + return ( ( xQUEUE * ) xQueue )->ucQueueType; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +static void +prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) +{ + if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 ) + { + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* The mutex is no longer being held. */ + vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder ); + pxQueue->pxMutexHolder = NULL; + } + } + #endif /* configUSE_MUTEXES */ + } + else if( xPosition == queueSEND_TO_BACK ) + { + ( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. */ + pxQueue->pcWriteTo += pxQueue->uxItemSize; + if( pxQueue->pcWriteTo >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->pcWriteTo = pxQueue->pcHead; + } + } + else + { + ( void ) memcpy( ( void * ) pxQueue->u.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + pxQueue->u.pcReadFrom -= pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->u.pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize ); + } + + if( xPosition == queueOVERWRITE ) + { + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + /* An item is not being added but overwritten, so subtract + one from the recorded number of items in the queue so when + one is added again below the number of recorded items remains + correct. */ + --( pxQueue->uxMessagesWaiting ); + } + } + } + + ++( pxQueue->uxMessagesWaiting ); +} +/*-----------------------------------------------------------*/ + +static void +prvCopyDataFromQueue( xQUEUE * const pxQueue, const void * const pvBuffer ) +{ + if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX ) + { + pxQueue->u.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */ + { + pxQueue->u.pcReadFrom = pxQueue->pcHead; + } + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */ + } +} +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvUnlockQueue( xQUEUE *pxQueue ) +{ + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ + + /* The lock counts contains the number of extra data items placed or + removed from the queue while the queue was locked. When a queue is + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + { + /* See if data was added to the queue while it was locked. */ + while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED ) + { + /* Data was posted while the queue was locked. Are any tasks + blocked waiting for data to become available? */ + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE ) + { + /* The queue is a member of a queue set, and posting to + the queue set caused a higher priority task to unblock. + A context switch is required. */ + vTaskMissedYield(); + } + } + else + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + } + } + else + { + break; + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + } + } + else + { + break; + } + } + #endif /* configUSE_QUEUE_SETS */ + + --( pxQueue->xTxLock ); + } + + pxQueue->xTxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + { + while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + vTaskMissedYield(); + } + + --( pxQueue->xRxLock ); + } + else + { + break; + } + } + + pxQueue->xRxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +static signed portBASE_TYPE ICACHE_FLASH_ATTR +prvIsQueueEmpty( const xQUEUE *pxQueue ) +{ +signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE ICACHE_FLASH_ATTR +xQueueIsQueueEmptyFromISR( const xQueueHandle xQueue ) +{ +signed portBASE_TYPE xReturn; + + configASSERT( xQueue ); + if( ( ( xQUEUE * ) xQueue )->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +static signed portBASE_TYPE ICACHE_FLASH_ATTR +prvIsQueueFull( const xQUEUE *pxQueue ) +{ +signed portBASE_TYPE xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE ICACHE_FLASH_ATTR +xQueueIsQueueFullFromISR( const xQueueHandle xQueue ) +{ +signed portBASE_TYPE xReturn; + + configASSERT( xQueue ); + if( ( ( xQUEUE * ) xQueue )->uxMessagesWaiting == ( ( xQUEUE * ) xQueue )->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + signed portBASE_TYPE ICACHE_FLASH_ATTR + xQueueCRSend( xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait ) + { + signed portBASE_TYPE xReturn; + xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + /* If the queue is already full we may have to block. A critical section + is required to prevent an interrupt removing something from the queue + between the check to see if the queue is full and blocking on the queue. */ + + //portDISABLE_INTERRUPTS(); +PortDisableInt_NoNest(); + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + /* The queue is full - do we want to block or just leave without + posting? */ + if( xTicksToWait > ( portTickType ) 0 ) + { + /* As this is called from a coroutine we cannot block directly, but + return indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); + //portENABLE_INTERRUPTS(); +PortEnableInt_NoNest(); + return errQUEUE_BLOCKED; + } + else + { + //portENABLE_INTERRUPTS(); +PortEnableInt_NoNest(); + return errQUEUE_FULL; + } + } + } + //portENABLE_INTERRUPTS(); +PortEnableInt_NoNest(); + + //portDISABLE_INTERRUPTS(); +PortDisableInt_NoNest(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The co-routine waiting has a higher priority so record + that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + } + } + } + else + { + xReturn = errQUEUE_FULL; + } + } + //portENABLE_INTERRUPTS(); +PortEnableInt_NoNest(); + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + signed portBASE_TYPE ICACHE_FLASH_ATTR + xQueueCRReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait ) + { + signed portBASE_TYPE xReturn; + xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + /* If the queue is already empty we may have to block. A critical section + is required to prevent an interrupt adding something to the queue + between the check to see if the queue is empty and blocking on the queue. */ + + //portDISABLE_INTERRUPTS(); +PortDisableInt_NoNest(); + { + if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 ) + { + /* There are no messages in the queue, do we want to block or just + leave with nothing? */ + if( xTicksToWait > ( portTickType ) 0 ) + { + /* As this is a co-routine we cannot block directly, but return + indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); + //portENABLE_INTERRUPTS(); +PortEnableInt_NoNest(); + return errQUEUE_BLOCKED; + } + else + { + //portENABLE_INTERRUPTS(); +PortEnableInt_NoNest(); + return errQUEUE_FULL; + } + } + } + //portENABLE_INTERRUPTS(); +PortEnableInt_NoNest(); + + //portDISABLE_INTERRUPTS(); +PortDisableInt_NoNest(); + { + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + /* Data is available from the queue. */ + pxQueue->u.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) + { + pxQueue->u.pcReadFrom = pxQueue->pcHead; + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + xReturn = errQUEUE_YIELD; + } + } + } + else + { + xReturn = pdFAIL; + } + } + //portENABLE_INTERRUPTS(); +PortEnableInt_NoNest(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + signed portBASE_TYPE ICACHE_FLASH_ATTR + xQueueCRSendFromISR( xQueueHandle xQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken ) + { + xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + /* Cannot block within an ISR so if there is no space on the queue then + exit without doing anything. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + + /* We only want to wake one co-routine per ISR, so check that a + co-routine has not already been woken. */ + if( xCoRoutinePreviouslyWoken == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + return pdTRUE; + } + } + } + } + + return xCoRoutinePreviouslyWoken; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + signed portBASE_TYPE ICACHE_FLASH_ATTR + xQueueCRReceiveFromISR( xQueueHandle xQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken ) + { + signed portBASE_TYPE xReturn; + xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + /* We cannot block from an ISR, so check there is data available. If + not then just leave without doing anything. */ + if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 ) + { + /* Copy the data from the queue. */ + pxQueue->u.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) + { + pxQueue->u.pcReadFrom = pxQueue->pcHead; + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + if( ( *pxCoRoutineWoken ) == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + *pxCoRoutineWoken = pdTRUE; + } + } + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void ICACHE_FLASH_ATTR + vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName ) + { + unsigned portBASE_TYPE ux; + + /* See if there is an empty space in the registry. A NULL name denotes + a free slot. */ + for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].pcQueueName == NULL ) + { + /* Store the information on this queue. */ + xQueueRegistry[ ux ].pcQueueName = pcQueueName; + xQueueRegistry[ ux ].xHandle = xQueue; + break; + } + } + } + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void ICACHE_FLASH_ATTR + vQueueUnregisterQueue( xQueueHandle xQueue ) + { + unsigned portBASE_TYPE ux; + + /* See if the handle of the queue being unregistered in actually in the + registry. */ + for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + /* Set the name to NULL to show that this slot if free again. */ + xQueueRegistry[ ux ].pcQueueName = NULL; + break; + } + } + + } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + + void ICACHE_FLASH_ATTR + vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait ) + { + xQUEUE * const pxQueue = ( xQUEUE * ) xQueue; + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements. + It can result in vListInsert() being called on a list that can only + possibly ever have one item in it, so the list will be fast, but even + so it should be called with the scheduler locked and not from a critical + section. */ + + /* Only do anything if there are no messages in the queue. This function + will not actually cause the task to block, just place it on a blocked + list. It will not block until the scheduler is unlocked - at which + time a yield will be performed. If an item is added to the queue while + the queue is locked, and the calling task blocks on the queue, then the + calling task will be immediately unblocked when the queue is unlocked. */ + prvLockQueue( pxQueue ); + if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0U ) + { + /* There is nothing in the queue, block for the specified period. */ + vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + } + prvUnlockQueue( pxQueue ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + xQueueSetHandle ICACHE_FLASH_ATTR + xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength ) + { + xQueueSetHandle pxQueue; + + pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( xQUEUE * ), queueQUEUE_TYPE_SET ); + + return pxQueue; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + portBASE_TYPE ICACHE_FLASH_ATTR + xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) + { + portBASE_TYPE xReturn; + + if( ( ( xQUEUE * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) + { + /* Cannot add a queue/semaphore to more than one queue set. */ + xReturn = pdFAIL; + } + else if( ( ( xQUEUE * ) xQueueOrSemaphore )->uxMessagesWaiting != ( unsigned portBASE_TYPE ) 0 ) + { + /* Cannot add a queue/semaphore to a queue set if there are already + items in the queue/semaphore. */ + xReturn = pdFAIL; + } + else + { + taskENTER_CRITICAL(); + { + ( ( xQUEUE * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet; + } + taskEXIT_CRITICAL(); + xReturn = pdPASS; + } + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + portBASE_TYPE ICACHE_FLASH_ATTR + xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) + { + portBASE_TYPE xReturn; + xQUEUE * const pxQueueOrSemaphore = ( xQUEUE * ) xQueueOrSemaphore; + + if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet ) + { + /* The queue was not a member of the set. */ + xReturn = pdFAIL; + } + else if( pxQueueOrSemaphore->uxMessagesWaiting != ( unsigned portBASE_TYPE ) 0 ) + { + /* It is dangerous to remove a queue from a set when the queue is + not empty because the queue set will still hold pending events for + the queue. */ + xReturn = pdFAIL; + } + else + { + taskENTER_CRITICAL(); + { + /* The queue is no longer contained in the set. */ + pxQueueOrSemaphore->pxQueueSetContainer = NULL; + } + taskEXIT_CRITICAL(); + xReturn = pdPASS; + } + + return xReturn; + } /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */ + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + xQueueSetMemberHandle ICACHE_FLASH_ATTR + xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) + { + xQueueSetMemberHandle xReturn = NULL; + + ( void ) xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + xQueueSetMemberHandle ICACHE_FLASH_ATTR + xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet ) + { + xQueueSetMemberHandle xReturn = NULL; + + ( void ) xQueueReceiveFromISR( ( xQueueHandle ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + static portBASE_TYPE ICACHE_FLASH_ATTR + prvNotifyQueueSetContainer( const xQUEUE * const pxQueue, portBASE_TYPE xCopyPosition ) + { + xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer; + portBASE_TYPE xReturn = pdFALSE; + + configASSERT( pxQueueSetContainer ); + configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ); + + if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ) + { + traceQUEUE_SEND( pxQueueSetContainer ); + /* The data copies is the handle of the queue that contains data. */ + prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition ); + if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority */ + xReturn = pdTRUE; + } + } + } + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ + diff --git a/third_party/freertos/readme.txt b/third_party/freertos/readme.txt index 81518ecb..58480c56 100644 --- a/third_party/freertos/readme.txt +++ b/third_party/freertos/readme.txt @@ -1,17 +1,17 @@ -Each real time kernel port consists of three files that contain the core kernel -components and are common to every port, and one or more files that are -specific to a particular microcontroller and or compiler. - -+ The FreeRTOS/Source directory contains the three files that are common to -every port - list.c, queue.c and tasks.c. The kernel is contained within these -three files. croutine.c implements the optional co-routine functionality - which -is normally only used on very memory limited systems. - -+ The FreeRTOS/Source/Portable directory contains the files that are specific to -a particular microcontroller and or compiler. - -+ The FreeRTOS/Source/include directory contains the real time kernel header -files. - -See the readme file in the FreeRTOS/Source/Portable directory for more +Each real time kernel port consists of three files that contain the core kernel +components and are common to every port, and one or more files that are +specific to a particular microcontroller and or compiler. + ++ The FreeRTOS/Source directory contains the three files that are common to +every port - list.c, queue.c and tasks.c. The kernel is contained within these +three files. croutine.c implements the optional co-routine functionality - which +is normally only used on very memory limited systems. + ++ The FreeRTOS/Source/Portable directory contains the files that are specific to +a particular microcontroller and or compiler. + ++ The FreeRTOS/Source/include directory contains the real time kernel header +files. + +See the readme file in the FreeRTOS/Source/Portable directory for more information. \ No newline at end of file diff --git a/third_party/freertos/tasks.c b/third_party/freertos/tasks.c index 1a6752bf..6de19f8e 100644 --- a/third_party/freertos/tasks.c +++ b/third_party/freertos/tasks.c @@ -1,3000 +1,3000 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -/* Standard includes. */ -#include -#include - -/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining -all the API functions to use the MPU wrappers. That should only be done when -task.h is included from an application file. */ -#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -/* FreeRTOS includes. */ -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/timers.h" -#include "freertos/StackMacros.h" - -/* Lint e961 and e750 are suppressed as a MISRA exception justified because the -MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the -header files above, but not in this file, in order to generate the correct -privileged Vs unprivileged linkage and placement. */ -#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ - -#if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) - /* At the bottom of this file are two optional functions that can be used - to generate human readable text from the raw data generated by the - uxTaskGetSystemState() function. Note the formatting functions are provided - for convenience only, and are NOT considered part of the kernel. */ - #include -#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) */ - -/* Sanity check the configuration. */ -#if configUSE_TICKLESS_IDLE != 0 - #if INCLUDE_vTaskSuspend != 1 - #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0 - #endif /* INCLUDE_vTaskSuspend */ -#endif /* configUSE_TICKLESS_IDLE */ - -/* - * Defines the size, in words, of the stack allocated to the idle task. - */ -#define tskIDLE_STACK_SIZE 384 - -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - -/* - * Task control block. A task control block (TCB) is allocated for each task, - * and stores task state information, including a pointer to the task's context - * (the task's run time environment, including register values) - */ -typedef struct tskTaskControlBlock -{ - volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ - - #if ( portUSING_MPU_WRAPPERS == 1 ) - xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ - #endif - - xListItem xGenericListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ - xListItem xEventListItem; /*< Used to reference a task from an event list. */ - unsigned portBASE_TYPE uxPriority; /*< The priority of the task. 0 is the lowest priority. */ - portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */ - signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ - - #if ( portSTACK_GROWTH > 0 ) - portSTACK_TYPE *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */ - #endif - - #if ( portCRITICAL_NESTING_IN_TCB == 1 ) - unsigned portBASE_TYPE uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ - #endif - - #if ( configUSE_TRACE_FACILITY == 1 ) - unsigned portBASE_TYPE uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ - unsigned portBASE_TYPE uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ - #endif - - #if ( configUSE_MUTEXES == 1 ) - unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ - #endif - - #if ( configUSE_APPLICATION_TASK_TAG == 1 ) - pdTASK_HOOK_CODE pxTaskTag; - #endif - - #if ( configGENERATE_RUN_TIME_STATS == 1 ) - unsigned long ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ - #endif - - #if ( configUSE_NEWLIB_REENTRANT == 1 ) - /* Allocate a Newlib reent structure that is specific to this task. - Note Newlib support has been included by popular demand, but is not - used by the FreeRTOS maintainers themselves. FreeRTOS is not - responsible for resulting newlib operation. User must be familiar with - newlib and must provide system-wide implementations of the necessary - stubs. Be warned that (at the time of writing) the current newlib design - implements a system-wide malloc() that must be provided with locks. */ - struct _reent xNewLib_reent; - #endif - -} tskTCB; - - -/* - * Some kernel aware debuggers require the data the debugger needs access to to - * be global, rather than file scope. - */ -#ifdef portREMOVE_STATIC_QUALIFIER - #define static -#endif - -/*lint -e956 A manual analysis and inspection has been used to determine which -static variables must be declared volatile. */ - -PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL; - -/* Lists for ready and blocked tasks. --------------------*/ -PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */ -PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */ -PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ -PRIVILEGED_DATA static xList * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ -PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ -PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ - -#if ( INCLUDE_vTaskDelete == 1 ) - - PRIVILEGED_DATA static xList xTasksWaitingTermination; /*< Tasks that have been deleted - but the their memory not yet freed. */ - PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0U; - -#endif - -#if ( INCLUDE_vTaskSuspend == 1 ) - - PRIVILEGED_DATA static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */ - -#endif - -#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) - - PRIVILEGED_DATA static xTaskHandle xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ - -#endif - -/* Other file private variables. --------------------------------*/ -PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0U; -PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0U; -PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY; -PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE; -PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE; -PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxPendedTicks = ( unsigned portBASE_TYPE ) 0U; -PRIVILEGED_DATA static volatile portBASE_TYPE xYieldPending = pdFALSE; -PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0; -PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0U; -PRIVILEGED_DATA static volatile portTickType xNextTaskUnblockTime = portMAX_DELAY; - -#if ( configGENERATE_RUN_TIME_STATS == 1 ) - - PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ - PRIVILEGED_DATA static unsigned long ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ - -#endif - -/*lint +e956 */ - -/* Debugging and trace facilities private variables and macros. ------------*/ - -/* - * The value used to fill the stack of a task when the task is created. This - * is used purely for checking the high water mark for tasks. - */ -#define tskSTACK_FILL_BYTE ( 0xa5U ) - -/* - * Macros used by vListTask to indicate which state a task is in. - */ -#define tskBLOCKED_CHAR ( ( signed char ) 'B' ) -#define tskREADY_CHAR ( ( signed char ) 'R' ) -#define tskDELETED_CHAR ( ( signed char ) 'D' ) -#define tskSUSPENDED_CHAR ( ( signed char ) 'S' ) - -/*-----------------------------------------------------------*/ - -#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) - - /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is - performed in a generic way that is not optimised to any particular - microcontroller architecture. */ - - /* uxTopReadyPriority holds the priority of the highest priority ready - state task. */ - #define taskRECORD_READY_PRIORITY( uxPriority ) \ - { \ - if( ( uxPriority ) > uxTopReadyPriority ) \ - { \ - uxTopReadyPriority = ( uxPriority ); \ - } \ - } /* taskRECORD_READY_PRIORITY */ - - /*-----------------------------------------------------------*/ - - #define taskSELECT_HIGHEST_PRIORITY_TASK() \ - { \ - /* Find the highest priority queue that contains ready tasks. */ \ - while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) \ - { \ - configASSERT( uxTopReadyPriority ); \ - --uxTopReadyPriority; \ - } \ - \ - /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ - the same priority get an equal share of the processor time. */ \ - listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); \ - } /* taskSELECT_HIGHEST_PRIORITY_TASK */ - - /*-----------------------------------------------------------*/ - - /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as - they are only required when a port optimised method of task selection is - being used. */ - #define taskRESET_READY_PRIORITY( uxPriority ) - #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) - -#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ - - /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is - performed in a way that is tailored to the particular microcontroller - architecture being used. */ - - /* A port optimised version is provided. Call the port defined macros. */ - #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) - - /*-----------------------------------------------------------*/ - - #define taskSELECT_HIGHEST_PRIORITY_TASK() \ - { \ - unsigned portBASE_TYPE uxTopPriority; \ - \ - /* Find the highest priority queue that contains ready tasks. */ \ - portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ - configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ - listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ - } /* taskSELECT_HIGHEST_PRIORITY_TASK() */ - - /*-----------------------------------------------------------*/ - - /* A port optimised version is provided, call it only if the TCB being reset - is being referenced from a ready list. If it is referenced from a delayed - or suspended list then it won't be in a ready list. */ - #define taskRESET_READY_PRIORITY( uxPriority ) \ - { \ - if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == 0 ) \ - { \ - portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ - } \ - } - -#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ - -/*-----------------------------------------------------------*/ - -/* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick -count overflows. */ -#define taskSWITCH_DELAYED_LISTS() \ -{ \ - xList *pxTemp; \ - \ - /* The delayed tasks list should be empty when the lists are switched. */ \ - configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \ - \ - pxTemp = pxDelayedTaskList; \ - pxDelayedTaskList = pxOverflowDelayedTaskList; \ - pxOverflowDelayedTaskList = pxTemp; \ - xNumOfOverflows++; \ - \ - if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \ - { \ - /* The new current delayed list is empty. Set \ - xNextTaskUnblockTime to the maximum possible value so it is \ - extremely unlikely that the \ - if( xTickCount >= xNextTaskUnblockTime ) test will pass until \ - there is an item in the delayed list. */ \ - xNextTaskUnblockTime = portMAX_DELAY; \ - } \ - else \ - { \ - /* The new current delayed list is not empty, get the value of \ - the item at the head of the delayed list. This is the time at \ - which the task at the head of the delayed list should be removed \ - from the Blocked state. */ \ - pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \ - xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); \ - } \ -} - -/*-----------------------------------------------------------*/ - -/* - * Place the task represented by pxTCB into the appropriate ready list for - * the task. It is inserted at the end of the list. - */ -#define prvAddTaskToReadyList( pxTCB ) \ - traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ - taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ - vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) ) -/*-----------------------------------------------------------*/ - -/* - * Several functions take an xTaskHandle parameter that can optionally be NULL, - * where NULL is used to indicate that the handle of the currently executing - * task should be used in place of the parameter. This macro simply checks to - * see if the parameter is NULL and returns a pointer to the appropriate TCB. - */ -#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) ( pxHandle ) ) - -/* Callback function prototypes. --------------------------*/ -extern void vApplicationStackOverflowHook( xTaskHandle xTask, signed char *pcTaskName ); -extern void vApplicationTickHook( void ); - -/* File private functions. --------------------------------*/ - -/* - * Utility to ready a TCB for a given task. Mainly just copies the parameters - * into the TCB structure. - */ -static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) PRIVILEGED_FUNCTION; - -/* - * Utility to ready all the lists used by the scheduler. This is called - * automatically upon the creation of the first task. - */ -static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; - -/* - * The idle task, which as all tasks is implemented as a never ending loop. - * The idle task is automatically created and added to the ready lists upon - * creation of the first user task. - * - * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific - * language extensions. The equivalent prototype for this function is: - * - * void prvIdleTask( void *pvParameters ); - * - */ -static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ); - -/* - * Utility to free all memory allocated by the scheduler to hold a TCB, - * including the stack pointed to by the TCB. - * - * This does not free memory allocated by the task itself (i.e. memory - * allocated by calls to pvPortMalloc from within the tasks application code). - */ -#if ( INCLUDE_vTaskDelete == 1 ) - - static void prvDeleteTCB( tskTCB *pxTCB ) PRIVILEGED_FUNCTION; - -#endif - -/* - * Used only by the idle task. This checks to see if anything has been placed - * in the list of tasks waiting to be deleted. If so the task is cleaned up - * and its TCB deleted. - */ -static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; - -/* - * The currently executing task is entering the Blocked state. Add the task to - * either the current or the overflow delayed task list. - */ -static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) PRIVILEGED_FUNCTION; - -/* - * Allocates memory from the heap for a TCB and associated stack. Checks the - * allocation was successful. - */ -static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) PRIVILEGED_FUNCTION; - -/* - * Fills an xTaskStatusType structure with information on each task that is - * referenced from the pxList list (which may be a ready list, a delayed list, - * a suspended list, etc.). - * - * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM - * NORMAL APPLICATION CODE. - */ -#if ( configUSE_TRACE_FACILITY == 1 ) - - static unsigned portBASE_TYPE prvListTaskWithinSingleList( xTaskStatusType *pxTaskStatusArray, xList *pxList, eTaskState eState ) PRIVILEGED_FUNCTION; - -#endif - -/* - * When a task is created, the stack of the task is filled with a known value. - * This function determines the 'high water mark' of the task stack by - * determining how much of the stack remains at the original preset value. - */ -#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) - - static unsigned short prvTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) PRIVILEGED_FUNCTION; - -#endif - -/* - * Return the amount of time, in ticks, that will pass before the kernel will - * next move a task from the Blocked state to the Running state. - * - * This conditional compilation should use inequality to 0, not equality to 1. - * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user - * defined low power mode implementations require configUSE_TICKLESS_IDLE to be - * set to a value other than 1. - */ -#if ( configUSE_TICKLESS_IDLE != 0 ) - - //static portTickType prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; - //portTickType ICACHE_FLASH_ATTR prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; -#endif - -signed portBASE_TYPE ICACHE_FLASH_ATTR -xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) -{ -signed portBASE_TYPE xReturn; -tskTCB * pxNewTCB; - - configASSERT( pxTaskCode ); - configASSERT( ( ( uxPriority & ( ~portPRIVILEGE_BIT ) ) < configMAX_PRIORITIES ) ); - - /* Allocate the memory required by the TCB and stack for the new task, - checking that the allocation was successful. */ - pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer ); - - if( pxNewTCB != NULL ) - { - portSTACK_TYPE *pxTopOfStack; - - #if( portUSING_MPU_WRAPPERS == 1 ) - /* Should the task be created in privileged mode? */ - portBASE_TYPE xRunPrivileged; - if( ( uxPriority & portPRIVILEGE_BIT ) != 0U ) - { - xRunPrivileged = pdTRUE; - } - else - { - xRunPrivileged = pdFALSE; - } - uxPriority &= ~portPRIVILEGE_BIT; - #endif /* portUSING_MPU_WRAPPERS == 1 */ - - /* Calculate the top of stack address. This depends on whether the - stack grows from high memory to low (as per the 80x86) or visa versa. - portSTACK_GROWTH is used to make the result positive or negative as - required by the port. */ - #if( portSTACK_GROWTH < 0 ) - { - pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( unsigned short ) 1 ); - pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */ - - /* Check the alignment of the calculated top of stack is correct. */ - configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); - } - #else /* portSTACK_GROWTH */ - { - pxTopOfStack = pxNewTCB->pxStack; - - /* Check the alignment of the stack buffer is correct. */ - configASSERT( ( ( ( unsigned long ) pxNewTCB->pxStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); - - /* If we want to use stack checking on architectures that use - a positive stack growth direction then we also need to store the - other extreme of the stack space. */ - pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ); - } - #endif /* portSTACK_GROWTH */ - - /* Setup the newly allocated TCB with the initial state of the task. */ - prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth ); - - /* Initialize the TCB stack to look as if the task was already running, - but had been interrupted by the scheduler. The return address is set - to the start of the task function. Once the stack has been initialised - the top of stack variable is updated. */ - #if( portUSING_MPU_WRAPPERS == 1 ) - { - pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); - } - #else /* portUSING_MPU_WRAPPERS */ - { - pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); - } - #endif /* portUSING_MPU_WRAPPERS */ - - if( ( void * ) pxCreatedTask != NULL ) - { - /* Pass the TCB out - in an anonymous way. The calling function/ - task can use this as a handle to delete the task later if - required.*/ - *pxCreatedTask = ( xTaskHandle ) pxNewTCB; - } - - /* Ensure interrupts don't access the task lists while they are being - updated. */ - taskENTER_CRITICAL(); - { - uxCurrentNumberOfTasks++; - if( pxCurrentTCB == NULL ) - { - /* There are no other tasks, or all the other tasks are in - the suspended state - make this the current task. */ - pxCurrentTCB = pxNewTCB; - - if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 ) - { - /* This is the first task to be created so do the preliminary - initialisation required. We will not recover if this call - fails, but we will report the failure. */ - prvInitialiseTaskLists(); - } - } - else - { - /* If the scheduler is not already running, make this task the - current task if it is the highest priority task to be created - so far. */ - if( xSchedulerRunning == pdFALSE ) - { - if( pxCurrentTCB->uxPriority <= uxPriority ) - { - pxCurrentTCB = pxNewTCB; - } - } - } - - uxTaskNumber++; - - #if ( configUSE_TRACE_FACILITY == 1 ) - { - /* Add a counter into the TCB for tracing only. */ - pxNewTCB->uxTCBNumber = uxTaskNumber; - } - #endif /* configUSE_TRACE_FACILITY */ - traceTASK_CREATE( pxNewTCB ); - - prvAddTaskToReadyList( pxNewTCB ); - - xReturn = pdPASS; - portSETUP_TCB( pxNewTCB ); - } - taskEXIT_CRITICAL(); - } - else - { - xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; - traceTASK_CREATE_FAILED(); - } - - if( xReturn == pdPASS ) - { - if( xSchedulerRunning != pdFALSE ) - { - /* If the created task is of a higher priority than the current task - then it should run now. */ - if( pxCurrentTCB->uxPriority < uxPriority ) - { - portYIELD_WITHIN_API(); - } - } - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_vTaskDelete == 1 ) - - void ICACHE_FLASH_ATTR - vTaskDelete( xTaskHandle xTaskToDelete ) - { - tskTCB *pxTCB; - - taskENTER_CRITICAL(); - { - /* If null is passed in here then we are deleting ourselves. */ - pxTCB = prvGetTCBFromHandle( xTaskToDelete ); - - /* Remove task from the ready list and place in the termination list. - This will stop the task from be scheduled. The idle task will check - the termination list and free up any memory allocated by the - scheduler for the TCB and stack. */ - if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) - { - taskRESET_READY_PRIORITY( pxTCB->uxPriority ); - } - - /* Is the task waiting on an event also? */ - if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) - { - ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); - } - - vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) ); - - /* Increment the ucTasksDeleted variable so the idle task knows - there is a task that has been deleted and that it should therefore - check the xTasksWaitingTermination list. */ - ++uxTasksDeleted; - - /* Increment the uxTaskNumberVariable also so kernel aware debuggers - can detect that the task lists need re-generating. */ - uxTaskNumber++; - - traceTASK_DELETE( pxTCB ); - } - taskEXIT_CRITICAL(); - - /* Force a reschedule if we have just deleted the current task. */ - if( xSchedulerRunning != pdFALSE ) - { - if( pxTCB == pxCurrentTCB ) - { - portYIELD_WITHIN_API(); - } - } - } - -#endif /* INCLUDE_vTaskDelete */ -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_vTaskDelayUntil == 1 ) - - void ICACHE_FLASH_ATTR - vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) - { - portTickType xTimeToWake; - portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE; - - configASSERT( pxPreviousWakeTime ); - configASSERT( ( xTimeIncrement > 0U ) ); - - vTaskSuspendAll(); - { - /* Minor optimisation. The tick count cannot change in this - block. */ - const portTickType xConstTickCount = xTickCount; - - /* Generate the tick time at which the task wants to wake. */ - xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; - - if( xConstTickCount < *pxPreviousWakeTime ) - { - /* The tick count has overflowed since this function was - lasted called. In this case the only time we should ever - actually delay is if the wake time has also overflowed, - and the wake time is greater than the tick time. When this - is the case it is as if neither time had overflowed. */ - if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) - { - xShouldDelay = pdTRUE; - } - } - else - { - /* The tick time has not overflowed. In this case we will - delay if either the wake time has overflowed, and/or the - tick time is less than the wake time. */ - if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) - { - xShouldDelay = pdTRUE; - } - } - - /* Update the wake time ready for the next call. */ - *pxPreviousWakeTime = xTimeToWake; - - if( xShouldDelay != pdFALSE ) - { - traceTASK_DELAY_UNTIL(); - - /* We must remove ourselves from the ready list before adding - ourselves to the blocked list as the same list item is used for - both lists. */ - if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) - { - /* The current task must be in a ready list, so there is - no need to check, and the port reset macro can be called - directly. */ - portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); - } - - prvAddCurrentTaskToDelayedList( xTimeToWake ); - } - } - xAlreadyYielded = xTaskResumeAll(); - - /* Force a reschedule if xTaskResumeAll has not already done so, we may - have put ourselves to sleep. */ - if( xAlreadyYielded == pdFALSE ) - { - portYIELD_WITHIN_API(); - } - } - -#endif /* INCLUDE_vTaskDelayUntil */ -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_vTaskDelay == 1 ) - - void ICACHE_FLASH_ATTR - vTaskDelay( portTickType xTicksToDelay ) - { - portTickType xTimeToWake; - signed portBASE_TYPE xAlreadyYielded = pdFALSE; - - /* A delay time of zero just forces a reschedule. */ - if( xTicksToDelay > ( portTickType ) 0U ) - { - vTaskSuspendAll(); - { - traceTASK_DELAY(); - - /* A task that is removed from the event list while the - scheduler is suspended will not get placed in the ready - list or removed from the blocked list until the scheduler - is resumed. - - This task cannot be in an event list as it is the currently - executing task. */ - - /* Calculate the time to wake - this may overflow but this is - not a problem. */ - xTimeToWake = xTickCount + xTicksToDelay; - - /* We must remove ourselves from the ready list before adding - ourselves to the blocked list as the same list item is used for - both lists. */ - if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) - { - /* The current task must be in a ready list, so there is - no need to check, and the port reset macro can be called - directly. */ - portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); - } - prvAddCurrentTaskToDelayedList( xTimeToWake ); - } - xAlreadyYielded = xTaskResumeAll(); - } - - /* Force a reschedule if xTaskResumeAll has not already done so, we may - have put ourselves to sleep. */ - if( xAlreadyYielded == pdFALSE ) - { - portYIELD_WITHIN_API(); - } - } - -#endif /* INCLUDE_vTaskDelay */ -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_eTaskGetState == 1 ) - - eTaskState ICACHE_FLASH_ATTR - eTaskGetState( xTaskHandle xTask ) - { - eTaskState eReturn; - xList *pxStateList; - const tskTCB * const pxTCB = ( tskTCB * ) xTask; - - if( pxTCB == pxCurrentTCB ) - { - /* The task calling this function is querying its own state. */ - eReturn = eRunning; - } - else - { - taskENTER_CRITICAL(); - { - pxStateList = ( xList * ) listLIST_ITEM_CONTAINER( &( pxTCB->xGenericListItem ) ); - } - taskEXIT_CRITICAL(); - - if( ( pxStateList == pxDelayedTaskList ) || ( pxStateList == pxOverflowDelayedTaskList ) ) - { - /* The task being queried is referenced from one of the Blocked - lists. */ - eReturn = eBlocked; - } - - #if ( INCLUDE_vTaskSuspend == 1 ) - else if( pxStateList == &xSuspendedTaskList ) - { - /* The task being queried is referenced from the suspended - list. */ - eReturn = eSuspended; - } - #endif - - #if ( INCLUDE_vTaskDelete == 1 ) - else if( pxStateList == &xTasksWaitingTermination ) - { - /* The task being queried is referenced from the deleted - tasks list. */ - eReturn = eDeleted; - } - #endif - - else - { - /* If the task is not in any other state, it must be in the - Ready (including pending ready) state. */ - eReturn = eReady; - } - } - - return eReturn; - } - -#endif /* INCLUDE_eTaskGetState */ -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_uxTaskPriorityGet == 1 ) - - unsigned portBASE_TYPE ICACHE_FLASH_ATTR - uxTaskPriorityGet( xTaskHandle xTask ) - { - tskTCB *pxTCB; - unsigned portBASE_TYPE uxReturn; - - taskENTER_CRITICAL(); - { - /* If null is passed in here then we are changing the - priority of the calling function. */ - pxTCB = prvGetTCBFromHandle( xTask ); - uxReturn = pxTCB->uxPriority; - } - taskEXIT_CRITICAL(); - - return uxReturn; - } - -#endif /* INCLUDE_uxTaskPriorityGet */ -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_vTaskPrioritySet == 1 ) - - void ICACHE_FLASH_ATTR - vTaskPrioritySet( xTaskHandle xTask, unsigned portBASE_TYPE uxNewPriority ) - { - tskTCB *pxTCB; - unsigned portBASE_TYPE uxCurrentBasePriority, uxPriorityUsedOnEntry; - portBASE_TYPE xYieldRequired = pdFALSE; - - configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) ); - - /* Ensure the new priority is valid. */ - if( uxNewPriority >= ( unsigned portBASE_TYPE ) configMAX_PRIORITIES ) - { - uxNewPriority = ( unsigned portBASE_TYPE ) configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U; - } - - taskENTER_CRITICAL(); - { - /* If null is passed in here then it is the priority of the calling - task that is being changed. */ - pxTCB = prvGetTCBFromHandle( xTask ); - - traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); - - #if ( configUSE_MUTEXES == 1 ) - { - uxCurrentBasePriority = pxTCB->uxBasePriority; - } - #else - { - uxCurrentBasePriority = pxTCB->uxPriority; - } - #endif - - if( uxCurrentBasePriority != uxNewPriority ) - { - /* The priority change may have readied a task of higher - priority than the calling task. */ - if( uxNewPriority > uxCurrentBasePriority ) - { - if( pxTCB != pxCurrentTCB ) - { - /* The priority of a task other than the currently - running task is being raised. Is the priority being - raised above that of the running task? */ - if( uxNewPriority >= pxCurrentTCB->uxPriority ) - { - xYieldRequired = pdTRUE; - } - } - else - { - /* The priority of the running task is being raised, - but the running task must already be the highest - priority task able to run so no yield is required. */ - } - } - else if( pxTCB == pxCurrentTCB ) - { - /* Setting the priority of the running task down means - there may now be another task of higher priority that - is ready to execute. */ - xYieldRequired = pdTRUE; - } - else - { - /* Setting the priority of any other task down does not - require a yield as the running task must be above the - new priority of the task being modified. */ - } - - /* Remember the ready list the task might be referenced from - before its uxPriority member is changed so the - taskRESET_READY_PRIORITY() macro can function correctly. */ - uxPriorityUsedOnEntry = pxTCB->uxPriority; - - #if ( configUSE_MUTEXES == 1 ) - { - /* Only change the priority being used if the task is not - currently using an inherited priority. */ - if( pxTCB->uxBasePriority == pxTCB->uxPriority ) - { - pxTCB->uxPriority = uxNewPriority; - } - - /* The base priority gets set whatever. */ - pxTCB->uxBasePriority = uxNewPriority; - } - #else - { - pxTCB->uxPriority = uxNewPriority; - } - #endif - - listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( portTickType ) configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - - /* If the task is in the blocked or suspended list we need do - nothing more than change it's priority variable. However, if - the task is in a ready list it needs to be removed and placed - in the list appropriate to its new priority. */ - if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE ) - { - /* The task is currently in its ready list - remove before adding - it to it's new ready list. As we are in a critical section we - can do this even if the scheduler is suspended. */ - if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) - { - /* It is known that the task is in its ready list so - there is no need to check again and the port level - reset macro can be called directly. */ - portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority ); - } - prvAddTaskToReadyList( pxTCB ); - } - - if( xYieldRequired == pdTRUE ) - { - portYIELD_WITHIN_API(); - } - - /* Remove compiler warning about unused variables when the port - optimised task selection is not being used. */ - ( void ) uxPriorityUsedOnEntry; - } - } - taskEXIT_CRITICAL(); - } - -#endif /* INCLUDE_vTaskPrioritySet */ -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_vTaskSuspend == 1 ) - - void ICACHE_FLASH_ATTR - vTaskSuspend( xTaskHandle xTaskToSuspend ) - { - tskTCB *pxTCB; - - taskENTER_CRITICAL(); - { - /* If null is passed in here then it is the running task that is - being suspended. */ - pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); - - traceTASK_SUSPEND( pxTCB ); - - /* Remove task from the ready/delayed list and place in the suspended list. */ - if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) - { - taskRESET_READY_PRIORITY( pxTCB->uxPriority ); - } - - /* Is the task waiting on an event also? */ - if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) - { - ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); - } - - vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ); - } - taskEXIT_CRITICAL(); - - if( pxTCB == pxCurrentTCB ) - { - if( xSchedulerRunning != pdFALSE ) - { - /* The current task has just been suspended. */ - portYIELD_WITHIN_API(); - } - else - { - /* The scheduler is not running, but the task that was pointed - to by pxCurrentTCB has just been suspended and pxCurrentTCB - must be adjusted to point to a different task. */ - if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) - { - /* No other tasks are ready, so set pxCurrentTCB back to - NULL so when the next task is created pxCurrentTCB will - be set to point to it no matter what its relative priority - is. */ - pxCurrentTCB = NULL; - } - else - { - vTaskSwitchContext(); - } - } - } - } - -#endif /* INCLUDE_vTaskSuspend */ -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_vTaskSuspend == 1 ) - - signed portBASE_TYPE ICACHE_FLASH_ATTR - xTaskIsTaskSuspended( xTaskHandle xTask ) - { - portBASE_TYPE xReturn = pdFALSE; - const tskTCB * const pxTCB = ( tskTCB * ) xTask; - - /* It does not make sense to check if the calling task is suspended. */ - configASSERT( xTask ); - - /* Is the task we are attempting to resume actually in the - suspended list? */ - if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) - { - /* Has the task already been resumed from within an ISR? */ - if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE ) - { - /* Is it in the suspended list because it is in the - Suspended state? It is possible to be in the suspended - list because it is blocked on a task with no timeout - specified. */ - if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) - { - xReturn = pdTRUE; - } - } - } - - return xReturn; - } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ - -#endif /* INCLUDE_vTaskSuspend */ -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_vTaskSuspend == 1 ) - - void ICACHE_FLASH_ATTR - vTaskResume( xTaskHandle xTaskToResume ) - { - tskTCB * const pxTCB = ( tskTCB * ) xTaskToResume; - - /* It does not make sense to resume the calling task. */ - configASSERT( xTaskToResume ); - - /* The parameter cannot be NULL as it is impossible to resume the - currently executing task. */ - if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) - { - taskENTER_CRITICAL(); - { - if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) - { - traceTASK_RESUME( pxTCB ); - - /* As we are in a critical section we can access the ready - lists even if the scheduler is suspended. */ - ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); - prvAddTaskToReadyList( pxTCB ); - - /* We may have just resumed a higher priority task. */ - if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) - { - /* This yield may not cause the task just resumed to run, but - will leave the lists in the correct state for the next yield. */ - portYIELD_WITHIN_API(); - } - } - } - taskEXIT_CRITICAL(); - } - } - -#endif /* INCLUDE_vTaskSuspend */ - -/*-----------------------------------------------------------*/ - -#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) - - portBASE_TYPE ICACHE_FLASH_ATTR - xTaskResumeFromISR( xTaskHandle xTaskToResume ) - { - portBASE_TYPE xYieldRequired = pdFALSE; - tskTCB * const pxTCB = ( tskTCB * ) xTaskToResume; - unsigned portBASE_TYPE uxSavedInterruptStatus; - - configASSERT( xTaskToResume ); - - /* RTOS ports that support interrupt nesting have the concept of a - maximum system call (or maximum API call) interrupt priority. - Interrupts that are above the maximum system call priority are keep - permanently enabled, even when the RTOS kernel is in a critical section, - but cannot make any calls to FreeRTOS API functions. If configASSERT() - is defined in FreeRTOSConfig.h then - portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion - failure if a FreeRTOS API function is called from an interrupt that has - been assigned a priority above the configured maximum system call - priority. Only FreeRTOS functions that end in FromISR can be called - from interrupts that have been assigned a priority at or (logically) - below the maximum system call interrupt priority. FreeRTOS maintains a - separate interrupt safe API to ensure interrupt entry is as fast and as - simple as possible. More information (albeit Cortex-M specific) is - provided on the following link: - http://www.freertos.org/RTOS-Cortex-M3-M4.html */ - portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - -// uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - portSET_INTERRUPT_MASK_FROM_ISR(); - - { - if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) - { - traceTASK_RESUME_FROM_ISR( pxTCB ); - - if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) - { - xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ); - ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); - prvAddTaskToReadyList( pxTCB ); - } - else - { - /* We cannot access the delayed or ready lists, so will hold this - task pending until the scheduler is resumed, at which point a - yield will be performed if necessary. */ - vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); - } - } - } - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); - - return xYieldRequired; - } - -#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ -/*-----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vTaskStartScheduler( void ) -{ -portBASE_TYPE xReturn; - - /* Add the idle task at the lowest priority. */ - #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) - { - /* Create the idle task, storing its handle in xIdleTaskHandle so it can - be returned by the xTaskGetIdleTaskHandle() function. */ - xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ - } - #else - { - /* Create the idle task without storing its handle. */ - xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ - } - #endif /* INCLUDE_xTaskGetIdleTaskHandle */ - - #if ( configUSE_TIMERS == 1 ) - { - if( xReturn == pdPASS ) - { - xReturn = xTimerCreateTimerTask(); - } - } - #endif /* configUSE_TIMERS */ - - if( xReturn == pdPASS ) - { - /* Interrupts are turned off here, to ensure a tick does not occur - before or during the call to xPortStartScheduler(). The stacks of - the created tasks contain a status word with interrupts switched on - so interrupts will automatically get re-enabled when the first task - starts to run. - - STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE - DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */ - //portDISABLE_INTERRUPTS(); -//PortDisableInt_NoNest(); - - xSchedulerRunning = pdTRUE; - xTickCount = ( portTickType ) 0U; - - /* If configGENERATE_RUN_TIME_STATS is defined then the following - macro must be defined to configure the timer/counter used to generate - the run time counter time base. */ - portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); - - /* Setting up the timer tick is hardware specific and thus in the - portable interface. */ - if( xPortStartScheduler() != pdFALSE ) - { - /* Should not reach here as if the scheduler is running the - function will not return. */ - } - else - { - /* Should only reach here if a task calls xTaskEndScheduler(). */ - } - } - else - { - /* This line will only be reached if the kernel could not be started, - because there was not enough FreeRTOS heap to create the idle task - or the timer task. */ - configASSERT( xReturn ); - } -} -/*-----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vTaskEndScheduler( void ) -{ - /* Stop the scheduler interrupts and call the portable scheduler end - routine so the original ISRs can be restored if necessary. The port - layer must ensure interrupts enable bit is left in the correct state. */ - - //portDISABLE_INTERRUPTS(); -PortDisableInt_NoNest(); - xSchedulerRunning = pdFALSE; - vPortEndScheduler(); -} -/*----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vTaskSuspendAll( void ) -{ - /* A critical section is not required as the variable is of type - portBASE_TYPE. */ - ++uxSchedulerSuspended; -} -/*----------------------------------------------------------*/ - -#if ( configUSE_TICKLESS_IDLE != 0 ) - - //static portTickType ICACHE_FLASH_ATTR - portTickType ICACHE_FLASH_ATTR prvGetExpectedIdleTime( void ) - { - portTickType xReturn; - - if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY ) - { - xReturn = 0; - } - else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 ) - { - /* There are other idle priority tasks in the ready state. If - time slicing is used then the very next tick interrupt must be - processed. */ - xReturn = 0; - } - else - { - xReturn = xNextTaskUnblockTime - xTickCount; - } - - return xReturn; - } - -#endif /* configUSE_TICKLESS_IDLE */ -/*----------------------------------------------------------*/ - -signed portBASE_TYPE ICACHE_FLASH_ATTR -xTaskResumeAll( void ) -{ -tskTCB *pxTCB; -portBASE_TYPE xAlreadyYielded = pdFALSE; -portBASE_TYPE xYieldRequired = pdFALSE; - - /* If uxSchedulerSuspended is zero then this function does not match a - previous call to vTaskSuspendAll(). */ - configASSERT( uxSchedulerSuspended ); - - /* It is possible that an ISR caused a task to be removed from an event - list while the scheduler was suspended. If this was the case then the - removed task will have been added to the xPendingReadyList. Once the - scheduler has been resumed it is safe to move all the pending ready - tasks from this list into their appropriate ready list. */ - taskENTER_CRITICAL(); - { - --uxSchedulerSuspended; - - if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) - { - if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0U ) - { - /* Move any readied tasks from the pending list into the - appropriate ready list. */ - while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE ) - { - pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); - ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); - ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); - prvAddTaskToReadyList( pxTCB ); - - /* If we have moved a task that has a priority higher than - the current task then we should yield. */ - if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) - { - xYieldRequired = pdTRUE; - } - } - - /* If any ticks occurred while the scheduler was suspended then - they should be processed now. This ensures the tick count does not - slip, and that any delayed tasks are resumed at the correct time. */ - if( uxPendedTicks > ( unsigned portBASE_TYPE ) 0U ) - { - while( uxPendedTicks > ( unsigned portBASE_TYPE ) 0U ) - { - if( xTaskIncrementTick() != pdFALSE ) - { - xYieldRequired = pdTRUE; - } - --uxPendedTicks; - } - } - - if( ( xYieldRequired == pdTRUE ) || ( xYieldPending == pdTRUE ) ) - { - xAlreadyYielded = pdTRUE; - xYieldPending = pdFALSE; - portYIELD_WITHIN_API(); - } - } - } - } - taskEXIT_CRITICAL(); - - return xAlreadyYielded; -} -/*-----------------------------------------------------------*/ - -portTickType ICACHE_FLASH_ATTR -xTaskGetTickCount( void ) -{ -portTickType xTicks; - - /* Critical section required if running on a 16 bit processor. */ - taskENTER_CRITICAL(); - { - xTicks = xTickCount; - } - taskEXIT_CRITICAL(); - - return xTicks; -} -/*-----------------------------------------------------------*/ - -portTickType ICACHE_FLASH_ATTR -xTaskGetTickCountFromISR( void ) -{ -portTickType xReturn; -unsigned portBASE_TYPE uxSavedInterruptStatus; - - /* RTOS ports that support interrupt nesting have the concept of a maximum - system call (or maximum API call) interrupt priority. Interrupts that are - above the maximum system call priority are keep permanently enabled, even - when the RTOS kernel is in a critical section, but cannot make any calls to - FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h - then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion - failure if a FreeRTOS API function is called from an interrupt that has been - assigned a priority above the configured maximum system call priority. - Only FreeRTOS functions that end in FromISR can be called from interrupts - that have been assigned a priority at or (logically) below the maximum - system call interrupt priority. FreeRTOS maintains a separate interrupt - safe API to ensure interrupt entry is as fast and as simple as possible. - More information (albeit Cortex-M specific) is provided on the following - link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ - portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); - -// uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); - portSET_INTERRUPT_MASK_FROM_ISR(); - - xReturn = xTickCount; - portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -unsigned portBASE_TYPE ICACHE_FLASH_ATTR -uxTaskGetNumberOfTasks( void ) -{ - /* A critical section is not required because the variables are of type - portBASE_TYPE. */ - return uxCurrentNumberOfTasks; -} -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_pcTaskGetTaskName == 1 ) - - signed char * ICACHE_FLASH_ATTR - pcTaskGetTaskName( xTaskHandle xTaskToQuery ) - { - tskTCB *pxTCB; - - /* If null is passed in here then the name of the calling task is being queried. */ - pxTCB = prvGetTCBFromHandle( xTaskToQuery ); - configASSERT( pxTCB ); - return &( pxTCB->pcTaskName[ 0 ] ); - } - -#endif /* INCLUDE_pcTaskGetTaskName */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - unsigned portBASE_TYPE ICACHE_FLASH_ATTR - uxTaskGetSystemState( xTaskStatusType *pxTaskStatusArray, unsigned portBASE_TYPE uxArraySize, unsigned long *pulTotalRunTime ) - { - unsigned portBASE_TYPE uxTask = 0, uxQueue = configMAX_PRIORITIES; - - vTaskSuspendAll(); - { - /* Is there a space in the array for each task in the system? */ - if( uxArraySize >= uxCurrentNumberOfTasks ) - { - /* Fill in an xTaskStatusType structure with information on each - task in the Ready state. */ - do - { - uxQueue--; - uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady ); - - } while( uxQueue > ( unsigned portBASE_TYPE ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - - /* Fill in an xTaskStatusType structure with information on each - task in the Blocked state. */ - uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( xList * ) pxDelayedTaskList, eBlocked ); - uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( xList * ) pxOverflowDelayedTaskList, eBlocked ); - - #if( INCLUDE_vTaskDelete == 1 ) - { - /* Fill in an xTaskStatusType structure with information on - each task that has been deleted but not yet cleaned up. */ - uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted ); - } - #endif - - #if ( INCLUDE_vTaskSuspend == 1 ) - { - /* Fill in an xTaskStatusType structure with information on - each task in the Suspended state. */ - uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended ); - } - #endif - - #if ( configGENERATE_RUN_TIME_STATS == 1) - { - if( pulTotalRunTime != NULL ) - { - *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); - } - } - #else - { - if( pulTotalRunTime != NULL ) - { - *pulTotalRunTime = 0; - } - } - #endif - } - } - ( void ) xTaskResumeAll(); - - return uxTask; - } - -#endif /* configUSE_TRACE_FACILITY */ -/*----------------------------------------------------------*/ - -#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) - - xTaskHandle ICACHE_FLASH_ATTR - xTaskGetIdleTaskHandle( void ) - { - /* If xTaskGetIdleTaskHandle() is called before the scheduler has been - started, then xIdleTaskHandle will be NULL. */ - configASSERT( ( xIdleTaskHandle != NULL ) ); - return xIdleTaskHandle; - } - -#endif /* INCLUDE_xTaskGetIdleTaskHandle */ -/*----------------------------------------------------------*/ - -/* This conditional compilation should use inequality to 0, not equality to 1. -This is to ensure vTaskStepTick() is available when user defined low power mode -implementations require configUSE_TICKLESS_IDLE to be set to a value other than -1. */ -#if ( configUSE_TICKLESS_IDLE != 0 ) - - void ICACHE_FLASH_ATTR - vTaskStepTick( portTickType xTicksToJump ) - { - /* Correct the tick count value after a period during which the tick - was suppressed. Note this does *not* call the tick hook function for - each stepped tick. */ - configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); - xTickCount += xTicksToJump; - traceINCREASE_TICK_COUNT( xTicksToJump ); - } - -#endif /* configUSE_TICKLESS_IDLE */ -/*----------------------------------------------------------*/ - -portBASE_TYPE -xTaskIncrementTick( void ) -{ -tskTCB * pxTCB; -portTickType xItemValue; -portBASE_TYPE xSwitchRequired = pdFALSE; - - /* Called by the portable layer each time a tick interrupt occurs. - Increments the tick then checks to see if the new tick value will cause any - tasks to be unblocked. */ - traceTASK_INCREMENT_TICK( xTickCount ); - if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) - { - /* Increment the RTOS tick, switching the delayed and overflowed - delayed lists if it wraps to 0. */ - ++xTickCount; - - { - /* Minor optimisation. The tick count cannot change in this - block. */ - const portTickType xConstTickCount = xTickCount; - - if( xConstTickCount == ( portTickType ) 0U ) - { - taskSWITCH_DELAYED_LISTS(); - } - - /* See if this tick has made a timeout expire. Tasks are stored in the - queue in the order of their wake time - meaning once one tasks has been - found whose block time has not expired there is no need not look any - further down the list. */ - if( xConstTickCount >= xNextTaskUnblockTime ) - { - for( ;; ) - { - if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) - { - /* The delayed list is empty. Set xNextTaskUnblockTime to - the maximum possible value so it is extremely unlikely that - the if( xTickCount >= xNextTaskUnblockTime ) test will pass - next time through. */ - xNextTaskUnblockTime = portMAX_DELAY; - break; - } - else - { - /* The delayed list is not empty, get the value of the item - at the head of the delayed list. This is the time at which - the task at the head of the delayed list must be removed - from the Blocked state. */ - pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); - xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); - - if( xConstTickCount < xItemValue ) - { - /* It is not time to unblock this item yet, but the item - value is the time at which the task at the head of the - blocked list must be removed from the Blocked state - - so record the item value in xNextTaskUnblockTime. */ - xNextTaskUnblockTime = xItemValue; - break; - } - - /* It is time to remove the item from the Blocked state. */ - ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); - - /* Is the task waiting on an event also? If so remove it - from the event list. */ - if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) - { - ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); - } - - /* Place the unblocked task into the appropriate ready - list. */ - prvAddTaskToReadyList( pxTCB ); - - /* A task being unblocked cannot cause an immediate context - switch if preemption is turned off. */ - #if ( configUSE_PREEMPTION == 1 ) - { - /* Preemption is on, but a context switch should only - be performed if the unblocked task has a priority that - is equal to or higher than the currently executing - task. */ - if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) - { - xSwitchRequired = pdTRUE; - } - } - #endif /* configUSE_PREEMPTION */ - } - } - } - } - - /* Tasks of equal priority to the currently running task will share - processing time (time slice) if preemption is on, and the application - writer has not explicitly turned time slicing off. */ - #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) - { - if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( unsigned portBASE_TYPE ) 1 ) - { - xSwitchRequired = pdTRUE; - } - } - #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ - } - else - { - ++uxPendedTicks; - - /* The tick hook gets called at regular intervals, even if the - scheduler is locked. */ - #if ( configUSE_TICK_HOOK == 1 ) - { - vApplicationTickHook(); - } - #endif - } - - #if ( configUSE_TICK_HOOK == 1 ) - { - /* Guard against the tick hook being called when the missed tick - count is being unwound (when the scheduler is being unlocked). */ - if( uxPendedTicks == ( unsigned portBASE_TYPE ) 0U ) - { - vApplicationTickHook(); - } - } - #endif /* configUSE_TICK_HOOK */ - - return xSwitchRequired; -} -/*-----------------------------------------------------------*/ - -#if ( configUSE_APPLICATION_TASK_TAG == 1 ) - - void ICACHE_FLASH_ATTR - vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) - { - tskTCB *xTCB; - - /* If xTask is NULL then we are setting our own task hook. */ - if( xTask == NULL ) - { - xTCB = ( tskTCB * ) pxCurrentTCB; - } - else - { - xTCB = ( tskTCB * ) xTask; - } - - /* Save the hook function in the TCB. A critical section is required as - the value can be accessed from an interrupt. */ - taskENTER_CRITICAL(); - xTCB->pxTaskTag = pxHookFunction; - taskEXIT_CRITICAL(); - } - -#endif /* configUSE_APPLICATION_TASK_TAG */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_APPLICATION_TASK_TAG == 1 ) - - pdTASK_HOOK_CODE ICACHE_FLASH_ATTR - xTaskGetApplicationTaskTag( xTaskHandle xTask ) - { - tskTCB *xTCB; - pdTASK_HOOK_CODE xReturn; - - /* If xTask is NULL then we are setting our own task hook. */ - if( xTask == NULL ) - { - xTCB = ( tskTCB * ) pxCurrentTCB; - } - else - { - xTCB = ( tskTCB * ) xTask; - } - - /* Save the hook function in the TCB. A critical section is required as - the value can be accessed from an interrupt. */ - taskENTER_CRITICAL(); - xReturn = xTCB->pxTaskTag; - taskEXIT_CRITICAL(); - - return xReturn; - } - -#endif /* configUSE_APPLICATION_TASK_TAG */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_APPLICATION_TASK_TAG == 1 ) - - portBASE_TYPE ICACHE_FLASH_ATTR - xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) - { - tskTCB *xTCB; - portBASE_TYPE xReturn; - - /* If xTask is NULL then we are calling our own task hook. */ - if( xTask == NULL ) - { - xTCB = ( tskTCB * ) pxCurrentTCB; - } - else - { - xTCB = ( tskTCB * ) xTask; - } - - if( xTCB->pxTaskTag != NULL ) - { - xReturn = xTCB->pxTaskTag( pvParameter ); - } - else - { - xReturn = pdFAIL; - } - - return xReturn; - } - -#endif /* configUSE_APPLICATION_TASK_TAG */ -/*-----------------------------------------------------------*/ - -void -vTaskSwitchContext( void ) -{ - if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE ) - { - /* The scheduler is currently suspended - do not allow a context - switch. */ - xYieldPending = pdTRUE; - } - else - { - traceTASK_SWITCHED_OUT(); - - #if ( configGENERATE_RUN_TIME_STATS == 1 ) - { - #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE - portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); - #else - ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); - #endif - - /* Add the amount of time the task has been running to the - accumulated time so far. The time the task started running was - stored in ulTaskSwitchedInTime. Note that there is no overflow - protection here so count values are only valid until the timer - overflows. The guard against negative values is to protect - against suspect run time stat counter implementations - which - are provided by the application, not the kernel. */ - if( ulTotalRunTime > ulTaskSwitchedInTime ) - { - pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); - } - ulTaskSwitchedInTime = ulTotalRunTime; - } - #endif /* configGENERATE_RUN_TIME_STATS */ - - taskFIRST_CHECK_FOR_STACK_OVERFLOW(); - taskSECOND_CHECK_FOR_STACK_OVERFLOW(); - - taskSELECT_HIGHEST_PRIORITY_TASK(); - - traceTASK_SWITCHED_IN(); - - #if ( configUSE_NEWLIB_REENTRANT == 1 ) - { - /* Switch Newlib's _impure_ptr variable to point to the _reent - structure specific to this task. */ - _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); - } - #endif /* configUSE_NEWLIB_REENTRANT */ - } -} -/*-----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vTaskPlaceOnEventList( xList * const pxEventList, portTickType xTicksToWait ) -{ -portTickType xTimeToWake; - - configASSERT( pxEventList ); - - /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE - SCHEDULER SUSPENDED. */ - - /* Place the event list item of the TCB in the appropriate event list. - This is placed in the list in priority order so the highest priority task - is the first to be woken by the event. */ - vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) ); - - /* We must remove ourselves from the ready list before adding ourselves - to the blocked list as the same list item is used for both lists. We have - exclusive access to the ready lists as the scheduler is locked. */ - if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) - { - /* The current task must be in a ready list, so there is no need to - check, and the port reset macro can be called directly. */ - portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); - } - - #if ( INCLUDE_vTaskSuspend == 1 ) - { - if( xTicksToWait == portMAX_DELAY ) - { - /* Add ourselves to the suspended task list instead of a delayed task - list to ensure we are not woken by a timing event. We will block - indefinitely. */ - vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) ); - } - else - { - /* Calculate the time at which the task should be woken if the event does - not occur. This may overflow but this doesn't matter. */ - xTimeToWake = xTickCount + xTicksToWait; - prvAddCurrentTaskToDelayedList( xTimeToWake ); - } - } - #else /* INCLUDE_vTaskSuspend */ - { - /* Calculate the time at which the task should be woken if the event does - not occur. This may overflow but this doesn't matter. */ - xTimeToWake = xTickCount + xTicksToWait; - prvAddCurrentTaskToDelayedList( xTimeToWake ); - } - #endif /* INCLUDE_vTaskSuspend */ -} -/*-----------------------------------------------------------*/ - -#if configUSE_TIMERS == 1 - - void ICACHE_FLASH_ATTR - vTaskPlaceOnEventListRestricted( xList * const pxEventList, portTickType xTicksToWait ) - { - portTickType xTimeToWake; - - configASSERT( pxEventList ); - - /* This function should not be called by application code hence the - 'Restricted' in its name. It is not part of the public API. It is - designed for use by kernel code, and has special calling requirements - - it should be called from a critical section. */ - - - /* Place the event list item of the TCB in the appropriate event list. - In this case it is assume that this is the only task that is going to - be waiting on this event list, so the faster vListInsertEnd() function - can be used in place of vListInsert. */ - vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); - - /* We must remove this task from the ready list before adding it to the - blocked list as the same list item is used for both lists. This - function is called form a critical section. */ - if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) - { - /* The current task must be in a ready list, so there is no need to - check, and the port reset macro can be called directly. */ - portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); - } - - /* Calculate the time at which the task should be woken if the event does - not occur. This may overflow but this doesn't matter. */ - xTimeToWake = xTickCount + xTicksToWait; - - traceTASK_DELAY_UNTIL(); - prvAddCurrentTaskToDelayedList( xTimeToWake ); - } - -#endif /* configUSE_TIMERS */ -/*-----------------------------------------------------------*/ - -signed portBASE_TYPE ICACHE_FLASH_ATTR -xTaskRemoveFromEventList( const xList * const pxEventList ) -{ -tskTCB *pxUnblockedTCB; -portBASE_TYPE xReturn; - - /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE - SCHEDULER SUSPENDED. It can also be called from within an ISR. */ - - /* The event list is sorted in priority order, so we can remove the - first in the list, remove the TCB from the delayed list, and add - it to the ready list. - - If an event is for a queue that is locked then this function will never - get called - the lock count on the queue will get modified instead. This - means we can always expect exclusive access to the event list here. - - This function assumes that a check has already been made to ensure that - pxEventList is not empty. */ - pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); - configASSERT( pxUnblockedTCB ); - ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); - - if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) - { - ( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) ); - prvAddTaskToReadyList( pxUnblockedTCB ); - } - else - { - /* We cannot access the delayed or ready lists, so will hold this - task pending until the scheduler is resumed. */ - vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); - } - - if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority ) - { - /* Return true if the task removed from the event list has - a higher priority than the calling task. This allows - the calling task to know if it should force a context - switch now. */ - xReturn = pdTRUE; - } - else - { - xReturn = pdFALSE; - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) -{ - configASSERT( pxTimeOut ); - pxTimeOut->xOverflowCount = xNumOfOverflows; - pxTimeOut->xTimeOnEntering = xTickCount; -} -/*-----------------------------------------------------------*/ - -portBASE_TYPE ICACHE_FLASH_ATTR -xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) -{ -portBASE_TYPE xReturn; - - configASSERT( pxTimeOut ); - configASSERT( pxTicksToWait ); - - taskENTER_CRITICAL(); - { - /* Minor optimisation. The tick count cannot change in this block. */ - const portTickType xConstTickCount = xTickCount; - - #if ( INCLUDE_vTaskSuspend == 1 ) - /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is - the maximum block time then the task should block indefinitely, and - therefore never time out. */ - if( *pxTicksToWait == portMAX_DELAY ) - { - xReturn = pdFALSE; - } - else /* We are not blocking indefinitely, perform the checks below. */ - #endif - - if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */ - { - /* The tick count is greater than the time at which vTaskSetTimeout() - was called, but has also overflowed since vTaskSetTimeOut() was called. - It must have wrapped all the way around and gone past us again. This - passed since vTaskSetTimeout() was called. */ - xReturn = pdTRUE; - } - else if( ( xConstTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait ) - { - /* Not a genuine timeout. Adjust parameters for time remaining. */ - *pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering ); - vTaskSetTimeOutState( pxTimeOut ); - xReturn = pdFALSE; - } - else - { - xReturn = pdTRUE; - } - } - taskEXIT_CRITICAL(); - - return xReturn; -} -/*-----------------------------------------------------------*/ - -void ICACHE_FLASH_ATTR -vTaskMissedYield( void ) -{ - xYieldPending = pdTRUE; -} -/*-----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - unsigned portBASE_TYPE ICACHE_FLASH_ATTR - uxTaskGetTaskNumber( xTaskHandle xTask ) - { - unsigned portBASE_TYPE uxReturn; - tskTCB *pxTCB; - - if( xTask != NULL ) - { - pxTCB = ( tskTCB * ) xTask; - uxReturn = pxTCB->uxTaskNumber; - } - else - { - uxReturn = 0U; - } - - return uxReturn; - } - -#endif /* configUSE_TRACE_FACILITY */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - void ICACHE_FLASH_ATTR - vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle ) - { - tskTCB *pxTCB; - - if( xTask != NULL ) - { - pxTCB = ( tskTCB * ) xTask; - pxTCB->uxTaskNumber = uxHandle; - } - } - -#endif /* configUSE_TRACE_FACILITY */ - -/* - * ----------------------------------------------------------- - * The Idle task. - * ---------------------------------------------------------- - * - * The portTASK_FUNCTION() macro is used to allow port/compiler specific - * language extensions. The equivalent prototype for this function is: - * - * void prvIdleTask( void *pvParameters ); - * - */ -static ICACHE_FLASH_ATTR -portTASK_FUNCTION( prvIdleTask, pvParameters ) -{ - /* Stop warnings. */ - ( void ) pvParameters; - - for( ;; ) - { - /* See if any tasks have been deleted. */ - prvCheckTasksWaitingTermination(); - - #if ( configUSE_PREEMPTION == 0 ) - { - /* If we are not using preemption we keep forcing a task switch to - see if any other task has become available. If we are using - preemption we don't need to do this as any task becoming available - will automatically get the processor anyway. */ - taskYIELD(); - } - #endif /* configUSE_PREEMPTION */ - - #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) - { - /* When using preemption tasks of equal priority will be - timesliced. If a task that is sharing the idle priority is ready - to run then the idle task should yield before the end of the - timeslice. - - A critical region is not required here as we are just reading from - the list, and an occasional incorrect value will not matter. If - the ready list at the idle priority contains more than one task - then a task other than the idle task is ready to execute. */ - if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( unsigned portBASE_TYPE ) 1 ) - { - taskYIELD(); - } - } - #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */ - - #if ( configUSE_IDLE_HOOK == 1 ) - { - extern void vApplicationIdleHook( void ); - - /* Call the user defined function from within the idle task. This - allows the application designer to add background functionality - without the overhead of a separate task. - NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, - CALL A FUNCTION THAT MIGHT BLOCK. */ - vApplicationIdleHook(); - } - #endif /* configUSE_IDLE_HOOK */ - - /* This conditional compilation should use inequality to 0, not equality - to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when - user defined low power mode implementations require - configUSE_TICKLESS_IDLE to be set to a value other than 1. */ - - //#if ( configUSE_TICKLESS_IDLE != 0 ) - #if 0 - { - portTickType xExpectedIdleTime; - - /* It is not desirable to suspend then resume the scheduler on - each iteration of the idle task. Therefore, a preliminary - test of the expected idle time is performed without the - scheduler suspended. The result here is not necessarily - valid. */ - xExpectedIdleTime = prvGetExpectedIdleTime(); - - if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) - { - vTaskSuspendAll(); - { - /* Now the scheduler is suspended, the expected idle - time can be sampled again, and this time its value can - be used. */ - configASSERT( xNextTaskUnblockTime >= xTickCount ); - xExpectedIdleTime = prvGetExpectedIdleTime(); - - if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) - { - traceLOW_POWER_IDLE_BEGIN(); - portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); - traceLOW_POWER_IDLE_END(); - } - } - ( void ) xTaskResumeAll(); - } - } - #endif /* configUSE_TICKLESS_IDLE */ - } -} -/*-----------------------------------------------------------*/ - -#if configUSE_TICKLESS_IDLE != 0 - - eSleepModeStatus ICACHE_FLASH_ATTR - eTaskConfirmSleepModeStatus( void ) - { - eSleepModeStatus eReturn = eStandardSleep; - - if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 ) - { - /* A task was made ready while the scheduler was suspended. */ - eReturn = eAbortSleep; - } - else if( xYieldPending != pdFALSE ) - { - /* A yield was pended while the scheduler was suspended. */ - eReturn = eAbortSleep; - } - else - { - #if configUSE_TIMERS == 0 - { - /* The idle task exists in addition to the application tasks. */ - const unsigned portBASE_TYPE uxNonApplicationTasks = 1; - - /* If timers are not being used and all the tasks are in the - suspended list (which might mean they have an infinite block - time rather than actually being suspended) then it is safe to - turn all clocks off and just wait for external interrupts. */ - if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) ) - { - eReturn = eNoTasksWaitingTimeout; - } - } - #endif /* configUSE_TIMERS */ - } - - return eReturn; - } -#endif /* configUSE_TICKLESS_IDLE */ -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) -{ -unsigned portBASE_TYPE x; - - /* Store the task name in the TCB. */ - for( x = ( unsigned portBASE_TYPE ) 0; x < ( unsigned portBASE_TYPE ) configMAX_TASK_NAME_LEN; x++ ) - { - pxTCB->pcTaskName[ x ] = pcName[ x ]; - - /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than - configMAX_TASK_NAME_LEN characters just in case the memory after the - string is not accessible (extremely unlikely). */ - if( pcName[ x ] == 0x00 ) - { - break; - } - } - - /* Ensure the name string is terminated in the case that the string length - was greater or equal to configMAX_TASK_NAME_LEN. */ - pxTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = ( signed char ) '\0'; - - /* This is used as an array index so must ensure it's not too large. First - remove the privilege bit if one is present. */ - if( uxPriority >= ( unsigned portBASE_TYPE ) configMAX_PRIORITIES ) - { - uxPriority = ( unsigned portBASE_TYPE ) configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U; - } - - pxTCB->uxPriority = uxPriority; - #if ( configUSE_MUTEXES == 1 ) - { - pxTCB->uxBasePriority = uxPriority; - } - #endif /* configUSE_MUTEXES */ - - vListInitialiseItem( &( pxTCB->xGenericListItem ) ); - vListInitialiseItem( &( pxTCB->xEventListItem ) ); - - /* Set the pxTCB as a link back from the xListItem. This is so we can get - back to the containing TCB from a generic item in a list. */ - listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB ); - - /* Event lists are always in priority order. */ - listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( portTickType ) configMAX_PRIORITIES - ( portTickType ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); - - #if ( portCRITICAL_NESTING_IN_TCB == 1 ) - { - pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0U; - } - #endif /* portCRITICAL_NESTING_IN_TCB */ - - #if ( configUSE_APPLICATION_TASK_TAG == 1 ) - { - pxTCB->pxTaskTag = NULL; - } - #endif /* configUSE_APPLICATION_TASK_TAG */ - - #if ( configGENERATE_RUN_TIME_STATS == 1 ) - { - pxTCB->ulRunTimeCounter = 0UL; - } - #endif /* configGENERATE_RUN_TIME_STATS */ - - #if ( portUSING_MPU_WRAPPERS == 1 ) - { - vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth ); - } - #else /* portUSING_MPU_WRAPPERS */ - { - ( void ) xRegions; - ( void ) usStackDepth; - } - #endif /* portUSING_MPU_WRAPPERS */ - - #if ( configUSE_NEWLIB_REENTRANT == 1 ) - { - /* Initialise this task's Newlib reent structure. */ - _REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) ); - } - #endif /* configUSE_NEWLIB_REENTRANT */ -} -/*-----------------------------------------------------------*/ - -#if ( portUSING_MPU_WRAPPERS == 1 ) - - void ICACHE_FLASH_ATTR - vTaskAllocateMPURegions( xTaskHandle xTaskToModify, const xMemoryRegion * const xRegions ) - { - tskTCB *pxTCB; - - /* If null is passed in here then we are deleting ourselves. */ - pxTCB = prvGetTCBFromHandle( xTaskToModify ); - - vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); - } - -#endif /* portUSING_MPU_WRAPPERS */ -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvInitialiseTaskLists( void ) -{ -unsigned portBASE_TYPE uxPriority; - - for( uxPriority = ( unsigned portBASE_TYPE ) 0U; uxPriority < ( unsigned portBASE_TYPE ) configMAX_PRIORITIES; uxPriority++ ) - { - vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) ); - } - - vListInitialise( &xDelayedTaskList1 ); - vListInitialise( &xDelayedTaskList2 ); - vListInitialise( &xPendingReadyList ); - - #if ( INCLUDE_vTaskDelete == 1 ) - { - vListInitialise( &xTasksWaitingTermination ); - } - #endif /* INCLUDE_vTaskDelete */ - - #if ( INCLUDE_vTaskSuspend == 1 ) - { - vListInitialise( &xSuspendedTaskList ); - } - #endif /* INCLUDE_vTaskSuspend */ - - /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList - using list2. */ - pxDelayedTaskList = &xDelayedTaskList1; - pxOverflowDelayedTaskList = &xDelayedTaskList2; -} -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvCheckTasksWaitingTermination( void ) -{ - #if ( INCLUDE_vTaskDelete == 1 ) - { - portBASE_TYPE xListIsEmpty; - - /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called - too often in the idle task. */ - while( uxTasksDeleted > ( unsigned portBASE_TYPE ) 0U ) - { - vTaskSuspendAll(); - xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination ); - ( void ) xTaskResumeAll(); - - if( xListIsEmpty == pdFALSE ) - { - tskTCB *pxTCB; - - taskENTER_CRITICAL(); - { - pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); - ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); - --uxCurrentNumberOfTasks; - --uxTasksDeleted; - } - taskEXIT_CRITICAL(); - - prvDeleteTCB( pxTCB ); - } - } - } - #endif /* vTaskDelete */ -} -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) -{ - /* The list item will be inserted in wake time order. */ - listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); - - if( xTimeToWake < xTickCount ) - { - /* Wake time has overflowed. Place this item in the overflow list. */ - vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) ); - } - else - { - /* The wake time has not overflowed, so we can use the current block list. */ - vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) ); - - /* If the task entering the blocked state was placed at the head of the - list of blocked tasks then xNextTaskUnblockTime needs to be updated - too. */ - if( xTimeToWake < xNextTaskUnblockTime ) - { - xNextTaskUnblockTime = xTimeToWake; - } - } -} -/*-----------------------------------------------------------*/ - -static tskTCB * ICACHE_FLASH_ATTR -prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) -{ -tskTCB *pxNewTCB; - - /* Allocate space for the TCB. Where the memory comes from depends on - the implementation of the port malloc function. */ - pxNewTCB = ( tskTCB * ) os_malloc( sizeof( tskTCB ) ); - - if( pxNewTCB != NULL ) - { - /* Allocate space for the stack used by the task being created. - The base of the stack memory stored in the TCB so the task can - be deleted later if required. */ - pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - if( pxNewTCB->pxStack == NULL ) - { - /* Could not allocate the stack. Delete the allocated TCB. */ - os_free( pxNewTCB ); - pxNewTCB = NULL; - } - else - { - /* Just to help debugging. */ - ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( portSTACK_TYPE ) ); - } - } - - return pxNewTCB; -} -/*-----------------------------------------------------------*/ - -#if ( configUSE_TRACE_FACILITY == 1 ) - - static unsigned portBASE_TYPE ICACHE_FLASH_ATTR - prvListTaskWithinSingleList( xTaskStatusType *pxTaskStatusArray, xList *pxList, eTaskState eState ) - { - volatile tskTCB *pxNextTCB, *pxFirstTCB; - unsigned portBASE_TYPE uxTask = 0; - - if( listCURRENT_LIST_LENGTH( pxList ) > ( unsigned portBASE_TYPE ) 0 ) - { - listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); - - /* Populate an xTaskStatusType structure within the - pxTaskStatusArray array for each task that is referenced from - pxList. See the definition of xTaskStatusType in task.h for the - meaning of each xTaskStatusType structure member. */ - do - { - listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); - - pxTaskStatusArray[ uxTask ].xHandle = ( xTaskHandle ) pxNextTCB; - pxTaskStatusArray[ uxTask ].pcTaskName = ( const signed char * ) &( pxNextTCB->pcTaskName [ 0 ] ); - pxTaskStatusArray[ uxTask ].xTaskNumber = pxNextTCB->uxTCBNumber; - pxTaskStatusArray[ uxTask ].eCurrentState = eState; - pxTaskStatusArray[ uxTask ].uxCurrentPriority = pxNextTCB->uxPriority; - - #if ( configUSE_MUTEXES == 1 ) - { - pxTaskStatusArray[ uxTask ].uxBasePriority = pxNextTCB->uxBasePriority; - } - #else - { - pxTaskStatusArray[ uxTask ].uxBasePriority = 0; - } - #endif - - #if ( configGENERATE_RUN_TIME_STATS == 1 ) - { - pxTaskStatusArray[ uxTask ].ulRunTimeCounter = pxNextTCB->ulRunTimeCounter; - } - #else - { - pxTaskStatusArray[ uxTask ].ulRunTimeCounter = 0; - } - #endif - - #if ( portSTACK_GROWTH > 0 ) - { - ppxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack ); - } - #else - { - pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack ); - } - #endif - - uxTask++; - - } while( pxNextTCB != pxFirstTCB ); - } - - return uxTask; - } - -#endif /* configUSE_TRACE_FACILITY */ -/*-----------------------------------------------------------*/ - -#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) - - static unsigned short ICACHE_FLASH_ATTR - prvTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) - { - register unsigned short usCount = 0U; - - while( *pucStackByte == tskSTACK_FILL_BYTE ) - { - pucStackByte -= portSTACK_GROWTH; - usCount++; - } - - usCount /= sizeof( portSTACK_TYPE ); - - return usCount; - } - -#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */ -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) - - unsigned portBASE_TYPE ICACHE_FLASH_ATTR - uxTaskGetStackHighWaterMark( xTaskHandle xTask ) - { - tskTCB *pxTCB; - unsigned char *pcEndOfStack; - unsigned portBASE_TYPE uxReturn; - - pxTCB = prvGetTCBFromHandle( xTask ); - - #if portSTACK_GROWTH < 0 - { - pcEndOfStack = ( unsigned char * ) pxTCB->pxStack; - } - #else - { - pcEndOfStack = ( unsigned char * ) pxTCB->pxEndOfStack; - } - #endif - - uxReturn = ( unsigned portBASE_TYPE ) prvTaskCheckFreeStackSpace( pcEndOfStack ); - - return uxReturn; - } - -#endif /* INCLUDE_uxTaskGetStackHighWaterMark */ -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_vTaskDelete == 1 ) - - static void ICACHE_FLASH_ATTR - prvDeleteTCB( tskTCB *pxTCB ) - { - /* This call is required specifically for the TriCore port. It must be - above the vPortFree() calls. The call is also used by ports/demos that - want to allocate and clean RAM statically. */ - portCLEAN_UP_TCB( pxTCB ); - - /* Free up the memory allocated by the scheduler for the task. It is up to - the task to free any memory allocated at the application level. */ - vPortFreeAligned( pxTCB->pxStack ); - os_free( pxTCB ); - } - -#endif /* INCLUDE_vTaskDelete */ -/*-----------------------------------------------------------*/ - -#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) - - xTaskHandle ICACHE_FLASH_ATTR - xTaskGetCurrentTaskHandle( void ) - { - xTaskHandle xReturn; - - /* A critical section is not required as this is not called from - an interrupt and the current TCB will always be the same for any - individual execution thread. */ - xReturn = pxCurrentTCB; - - return xReturn; - } - -#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ -/*-----------------------------------------------------------*/ - -#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - - portBASE_TYPE ICACHE_FLASH_ATTR - xTaskGetSchedulerState( void ) - { - portBASE_TYPE xReturn; - - if( xSchedulerRunning == pdFALSE ) - { - xReturn = taskSCHEDULER_NOT_STARTED; - } - else - { - if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) - { - xReturn = taskSCHEDULER_RUNNING; - } - else - { - xReturn = taskSCHEDULER_SUSPENDED; - } - } - - return xReturn; - } - -#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_MUTEXES == 1 ) - - void ICACHE_FLASH_ATTR - vTaskPriorityInherit( xTaskHandle const pxMutexHolder ) - { - tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder; - - /* If the mutex was given back by an interrupt while the queue was - locked then the mutex holder might now be NULL. */ - if( pxMutexHolder != NULL ) - { - if( pxTCB->uxPriority < pxCurrentTCB->uxPriority ) - { - /* Adjust the mutex holder state to account for its new priority. */ - listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( portTickType ) configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - - /* If the task being modified is in the ready state it will need to - be moved into a new list. */ - if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE ) - { - if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) - { - taskRESET_READY_PRIORITY( pxTCB->uxPriority ); - } - - /* Inherit the priority before being moved into the new list. */ - pxTCB->uxPriority = pxCurrentTCB->uxPriority; - prvAddTaskToReadyList( pxTCB ); - } - else - { - /* Just inherit the priority. */ - pxTCB->uxPriority = pxCurrentTCB->uxPriority; - } - - traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority ); - } - } - } - -#endif /* configUSE_MUTEXES */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_MUTEXES == 1 ) - - void - vTaskPriorityDisinherit( xTaskHandle const pxMutexHolder ) - { - tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder; - - if( pxMutexHolder != NULL ) - { - if( pxTCB->uxPriority != pxTCB->uxBasePriority ) - { - /* We must be the running task to be able to give the mutex back. - Remove ourselves from the ready list we currently appear in. */ - if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) - { - taskRESET_READY_PRIORITY( pxTCB->uxPriority ); - } - - /* Disinherit the priority before adding the task into the new - ready list. */ - traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); - pxTCB->uxPriority = pxTCB->uxBasePriority; - listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( portTickType ) configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ - prvAddTaskToReadyList( pxTCB ); - } - } - } - -#endif /* configUSE_MUTEXES */ -/*-----------------------------------------------------------*/ - -#if ( portCRITICAL_NESTING_IN_TCB == 1 ) - - void ICACHE_FLASH_ATTR - vTaskEnterCritical( void ) - { - //portDISABLE_INTERRUPTS(); -PortDisableInt_NoNest(); - if( xSchedulerRunning != pdFALSE ) - { - ( pxCurrentTCB->uxCriticalNesting )++; - } - } - -#endif /* portCRITICAL_NESTING_IN_TCB */ -/*-----------------------------------------------------------*/ - -#if ( portCRITICAL_NESTING_IN_TCB == 1 ) - - void ICACHE_FLASH_ATTR - vTaskExitCritical( void ) - { - if( xSchedulerRunning != pdFALSE ) - { - if( pxCurrentTCB->uxCriticalNesting > 0U ) - { - ( pxCurrentTCB->uxCriticalNesting )--; - - if( pxCurrentTCB->uxCriticalNesting == 0U ) - { - //portENABLE_INTERRUPTS(); - PortEnableInt_NoNest(); - } - } - } - } - -#endif /* portCRITICAL_NESTING_IN_TCB */ -/*-----------------------------------------------------------*/ - -#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) - - void ICACHE_FLASH_ATTR - vTaskList( signed char *pcWriteBuffer ) - { - xTaskStatusType *pxTaskStatusArray; - volatile unsigned portBASE_TYPE uxArraySize, x; - char cStatus; - - /* - * PLEASE NOTE: - * - * This function is provided for convenience only, and is used by many - * of the demo applications. Do not consider it to be part of the - * scheduler. - * - * vTaskList() calls uxTaskGetSystemState(), then formats part of the - * uxTaskGetSystemState() output into a human readable table that - * displays task names, states and stack usage. - * - * vTaskList() has a dependency on the sprintf() C library function that - * might bloat the code size, use a lot of stack, and provide different - * results on different platforms. An alternative, tiny, third party, - * and limited functionality implementation of sprintf() is provided in - * many of the FreeRTOS/Demo sub-directories in a file called - * printf-stdarg.c (note printf-stdarg.c does not provide a full - * snprintf() implementation!). - * - * It is recommended that production systems call uxTaskGetSystemState() - * directly to get access to raw stats data, rather than indirectly - * through a call to vTaskList(). - */ - - - /* Make sure the write buffer does not contain a string. */ - *pcWriteBuffer = 0x00; - - /* Take a snapshot of the number of tasks in case it changes while this - function is executing. */ - uxArraySize = uxCurrentNumberOfTasks; - - /* Allocate an array index for each task. */ - pxTaskStatusArray = os_malloc( uxCurrentNumberOfTasks * sizeof( xTaskStatusType ) ); - - if( pxTaskStatusArray != NULL ) - { - /* Generate the (binary) data. */ - uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL ); - - /* Create a human readable table from the binary data. */ - for( x = 0; x < uxArraySize; x++ ) - { - switch( pxTaskStatusArray[ x ].eCurrentState ) - { - case eReady: cStatus = tskREADY_CHAR; - break; - - case eBlocked: cStatus = tskBLOCKED_CHAR; - break; - - case eSuspended: cStatus = tskSUSPENDED_CHAR; - break; - - case eDeleted: cStatus = tskDELETED_CHAR; - break; - - default: /* Should not get here, but it is included - to prevent static checking errors. */ - cStatus = 0x00; - break; - } - - sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxTaskStatusArray[ x ].pcTaskName, cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); - pcWriteBuffer += strlen( ( char * ) pcWriteBuffer ); - } - - /* Free the array again. */ - os_free( pxTaskStatusArray ); - } - } - -#endif /* configUSE_TRACE_FACILITY */ -/*----------------------------------------------------------*/ - -#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) - - void ICACHE_FLASH_ATTR - vTaskGetRunTimeStats( signed char *pcWriteBuffer ) - { - xTaskStatusType *pxTaskStatusArray; - volatile unsigned portBASE_TYPE uxArraySize, x; - unsigned long ulTotalTime, ulStatsAsPercentage; - - /* - * PLEASE NOTE: - * - * This function is provided for convenience only, and is used by many - * of the demo applications. Do not consider it to be part of the - * scheduler. - * - * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part - * of the uxTaskGetSystemState() output into a human readable table that - * displays the amount of time each task has spent in the Running state - * in both absolute and percentage terms. - * - * vTaskGetRunTimeStats() has a dependency on the sprintf() C library - * function that might bloat the code size, use a lot of stack, and - * provide different results on different platforms. An alternative, - * tiny, third party, and limited functionality implementation of - * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in - * a file called printf-stdarg.c (note printf-stdarg.c does not provide - * a full snprintf() implementation!). - * - * It is recommended that production systems call uxTaskGetSystemState() - * directly to get access to raw stats data, rather than indirectly - * through a call to vTaskGetRunTimeStats(). - */ - - /* Make sure the write buffer does not contain a string. */ - *pcWriteBuffer = 0x00; - - /* Take a snapshot of the number of tasks in case it changes while this - function is executing. */ - uxArraySize = uxCurrentNumberOfTasks; - - /* Allocate an array index for each task. */ - pxTaskStatusArray = os_malloc( uxCurrentNumberOfTasks * sizeof( xTaskStatusType ) ); - - if( pxTaskStatusArray != NULL ) - { - /* Generate the (binary) data. */ - uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime ); - - /* For percentage calculations. */ - ulTotalTime /= 100UL; - - /* Avoid divide by zero errors. */ - if( ulTotalTime > 0 ) - { - /* Create a human readable table from the binary data. */ - for( x = 0; x < uxArraySize; x++ ) - { - /* What percentage of the total run time has the task used? - This will always be rounded down to the nearest integer. - ulTotalRunTimeDiv100 has already been divided by 100. */ - ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime; - - if( ulStatsAsPercentage > 0UL ) - { - #ifdef portLU_PRINTF_SPECIFIER_REQUIRED - { - sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); - } - #else - { - /* sizeof( int ) == sizeof( long ) so a smaller - printf() library can be used. */ - sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxTaskStatusArray[ x ].pcTaskName, ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); - } - #endif - } - else - { - /* If the percentage is zero here then the task has - consumed less than 1% of the total run time. */ - #ifdef portLU_PRINTF_SPECIFIER_REQUIRED - { - sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter ); - } - #else - { - /* sizeof( int ) == sizeof( long ) so a smaller - printf() library can be used. */ - sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); - } - #endif - } - - pcWriteBuffer += strlen( ( char * ) pcWriteBuffer ); - } - } - - /* Free the array again. */ - os_free( pxTaskStatusArray ); - } - } - -#endif /* configGENERATE_RUN_TIME_STATS */ - - - +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* Standard includes. */ +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/timers.h" +#include "freertos/StackMacros.h" + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + +#if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) + /* At the bottom of this file are two optional functions that can be used + to generate human readable text from the raw data generated by the + uxTaskGetSystemState() function. Note the formatting functions are provided + for convenience only, and are NOT considered part of the kernel. */ + #include +#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) */ + +/* Sanity check the configuration. */ +#if configUSE_TICKLESS_IDLE != 0 + #if INCLUDE_vTaskSuspend != 1 + #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0 + #endif /* INCLUDE_vTaskSuspend */ +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Defines the size, in words, of the stack allocated to the idle task. + */ +#define tskIDLE_STACK_SIZE 384 + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; +#endif + +/* + * Task control block. A task control block (TCB) is allocated for each task, + * and stores task state information, including a pointer to the task's context + * (the task's run time environment, including register values) + */ +typedef struct tskTaskControlBlock +{ + volatile portSTACK_TYPE *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ + #endif + + xListItem xGenericListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ + xListItem xEventListItem; /*< Used to reference a task from an event list. */ + unsigned portBASE_TYPE uxPriority; /*< The priority of the task. 0 is the lowest priority. */ + portSTACK_TYPE *pxStack; /*< Points to the start of the stack. */ + signed char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ + + #if ( portSTACK_GROWTH > 0 ) + portSTACK_TYPE *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + unsigned portBASE_TYPE uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + unsigned portBASE_TYPE uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ + unsigned portBASE_TYPE uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + unsigned portBASE_TYPE uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + pdTASK_HOOK_CODE pxTaskTag; + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + unsigned long ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + /* Allocate a Newlib reent structure that is specific to this task. + Note Newlib support has been included by popular demand, but is not + used by the FreeRTOS maintainers themselves. FreeRTOS is not + responsible for resulting newlib operation. User must be familiar with + newlib and must provide system-wide implementations of the necessary + stubs. Be warned that (at the time of writing) the current newlib design + implements a system-wide malloc() that must be provided with locks. */ + struct _reent xNewLib_reent; + #endif + +} tskTCB; + + +/* + * Some kernel aware debuggers require the data the debugger needs access to to + * be global, rather than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + +/*lint -e956 A manual analysis and inspection has been used to determine which +static variables must be declared volatile. */ + +PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL; + +/* Lists for ready and blocked tasks. --------------------*/ +PRIVILEGED_DATA static xList pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */ +PRIVILEGED_DATA static xList xDelayedTaskList1; /*< Delayed tasks. */ +PRIVILEGED_DATA static xList xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ +PRIVILEGED_DATA static xList * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ +PRIVILEGED_DATA static xList * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ +PRIVILEGED_DATA static xList xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ + +#if ( INCLUDE_vTaskDelete == 1 ) + + PRIVILEGED_DATA static xList xTasksWaitingTermination; /*< Tasks that have been deleted - but the their memory not yet freed. */ + PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTasksDeleted = ( unsigned portBASE_TYPE ) 0U; + +#endif + +#if ( INCLUDE_vTaskSuspend == 1 ) + + PRIVILEGED_DATA static xList xSuspendedTaskList; /*< Tasks that are currently suspended. */ + +#endif + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + PRIVILEGED_DATA static xTaskHandle xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ + +#endif + +/* Other file private variables. --------------------------------*/ +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxCurrentNumberOfTasks = ( unsigned portBASE_TYPE ) 0U; +PRIVILEGED_DATA static volatile portTickType xTickCount = ( portTickType ) 0U; +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxTopReadyPriority = tskIDLE_PRIORITY; +PRIVILEGED_DATA static volatile signed portBASE_TYPE xSchedulerRunning = pdFALSE; +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxSchedulerSuspended = ( unsigned portBASE_TYPE ) pdFALSE; +PRIVILEGED_DATA static volatile unsigned portBASE_TYPE uxPendedTicks = ( unsigned portBASE_TYPE ) 0U; +PRIVILEGED_DATA static volatile portBASE_TYPE xYieldPending = pdFALSE; +PRIVILEGED_DATA static volatile portBASE_TYPE xNumOfOverflows = ( portBASE_TYPE ) 0; +PRIVILEGED_DATA static unsigned portBASE_TYPE uxTaskNumber = ( unsigned portBASE_TYPE ) 0U; +PRIVILEGED_DATA static volatile portTickType xNextTaskUnblockTime = portMAX_DELAY; + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + PRIVILEGED_DATA static unsigned long ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ + PRIVILEGED_DATA static unsigned long ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ + +#endif + +/*lint +e956 */ + +/* Debugging and trace facilities private variables and macros. ------------*/ + +/* + * The value used to fill the stack of a task when the task is created. This + * is used purely for checking the high water mark for tasks. + */ +#define tskSTACK_FILL_BYTE ( 0xa5U ) + +/* + * Macros used by vListTask to indicate which state a task is in. + */ +#define tskBLOCKED_CHAR ( ( signed char ) 'B' ) +#define tskREADY_CHAR ( ( signed char ) 'R' ) +#define tskDELETED_CHAR ( ( signed char ) 'D' ) +#define tskSUSPENDED_CHAR ( ( signed char ) 'S' ) + +/*-----------------------------------------------------------*/ + +#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is + performed in a generic way that is not optimised to any particular + microcontroller architecture. */ + + /* uxTopReadyPriority holds the priority of the highest priority ready + state task. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) \ + { \ + if( ( uxPriority ) > uxTopReadyPriority ) \ + { \ + uxTopReadyPriority = ( uxPriority ); \ + } \ + } /* taskRECORD_READY_PRIORITY */ + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + /* Find the highest priority queue that contains ready tasks. */ \ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) \ + { \ + configASSERT( uxTopReadyPriority ); \ + --uxTopReadyPriority; \ + } \ + \ + /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ + the same priority get an equal share of the processor time. */ \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK */ + + /*-----------------------------------------------------------*/ + + /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as + they are only required when a port optimised method of task selection is + being used. */ + #define taskRESET_READY_PRIORITY( uxPriority ) + #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + +#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is + performed in a way that is tailored to the particular microcontroller + architecture being used. */ + + /* A port optimised version is provided. Call the port defined macros. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + unsigned portBASE_TYPE uxTopPriority; \ + \ + /* Find the highest priority queue that contains ready tasks. */ \ + portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ + configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK() */ + + /*-----------------------------------------------------------*/ + + /* A port optimised version is provided, call it only if the TCB being reset + is being referenced from a ready list. If it is referenced from a delayed + or suspended list then it won't be in a ready list. */ + #define taskRESET_READY_PRIORITY( uxPriority ) \ + { \ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == 0 ) \ + { \ + portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ + } \ + } + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +/* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick +count overflows. */ +#define taskSWITCH_DELAYED_LISTS() \ +{ \ + xList *pxTemp; \ + \ + /* The delayed tasks list should be empty when the lists are switched. */ \ + configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \ + \ + pxTemp = pxDelayedTaskList; \ + pxDelayedTaskList = pxOverflowDelayedTaskList; \ + pxOverflowDelayedTaskList = pxTemp; \ + xNumOfOverflows++; \ + \ + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) \ + { \ + /* The new current delayed list is empty. Set \ + xNextTaskUnblockTime to the maximum possible value so it is \ + extremely unlikely that the \ + if( xTickCount >= xNextTaskUnblockTime ) test will pass until \ + there is an item in the delayed list. */ \ + xNextTaskUnblockTime = portMAX_DELAY; \ + } \ + else \ + { \ + /* The new current delayed list is not empty, get the value of \ + the item at the head of the delayed list. This is the time at \ + which the task at the head of the delayed list should be removed \ + from the Blocked state. */ \ + pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); \ + xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); \ + } \ +} + +/*-----------------------------------------------------------*/ + +/* + * Place the task represented by pxTCB into the appropriate ready list for + * the task. It is inserted at the end of the list. + */ +#define prvAddTaskToReadyList( pxTCB ) \ + traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) ) +/*-----------------------------------------------------------*/ + +/* + * Several functions take an xTaskHandle parameter that can optionally be NULL, + * where NULL is used to indicate that the handle of the currently executing + * task should be used in place of the parameter. This macro simply checks to + * see if the parameter is NULL and returns a pointer to the appropriate TCB. + */ +#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) ( pxHandle ) ) + +/* Callback function prototypes. --------------------------*/ +extern void vApplicationStackOverflowHook( xTaskHandle xTask, signed char *pcTaskName ); +extern void vApplicationTickHook( void ); + +/* File private functions. --------------------------------*/ + +/* + * Utility to ready a TCB for a given task. Mainly just copies the parameters + * into the TCB structure. + */ +static void prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) PRIVILEGED_FUNCTION; + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first task. + */ +static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; + +/* + * The idle task, which as all tasks is implemented as a never ending loop. + * The idle task is automatically created and added to the ready lists upon + * creation of the first user task. + * + * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ); + +/* + * Utility to free all memory allocated by the scheduler to hold a TCB, + * including the stack pointed to by the TCB. + * + * This does not free memory allocated by the task itself (i.e. memory + * allocated by calls to pvPortMalloc from within the tasks application code). + */ +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( tskTCB *pxTCB ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Used only by the idle task. This checks to see if anything has been placed + * in the list of tasks waiting to be deleted. If so the task is cleaned up + * and its TCB deleted. + */ +static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; + +/* + * The currently executing task is entering the Blocked state. Add the task to + * either the current or the overflow delayed task list. + */ +static void prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) PRIVILEGED_FUNCTION; + +/* + * Allocates memory from the heap for a TCB and associated stack. Checks the + * allocation was successful. + */ +static tskTCB *prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) PRIVILEGED_FUNCTION; + +/* + * Fills an xTaskStatusType structure with information on each task that is + * referenced from the pxList list (which may be a ready list, a delayed list, + * a suspended list, etc.). + * + * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM + * NORMAL APPLICATION CODE. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + static unsigned portBASE_TYPE prvListTaskWithinSingleList( xTaskStatusType *pxTaskStatusArray, xList *pxList, eTaskState eState ) PRIVILEGED_FUNCTION; + +#endif + +/* + * When a task is created, the stack of the task is filled with a known value. + * This function determines the 'high water mark' of the task stack by + * determining how much of the stack remains at the original preset value. + */ +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + + static unsigned short prvTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Return the amount of time, in ticks, that will pass before the kernel will + * next move a task from the Blocked state to the Running state. + * + * This conditional compilation should use inequality to 0, not equality to 1. + * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user + * defined low power mode implementations require configUSE_TICKLESS_IDLE to be + * set to a value other than 1. + */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + //static portTickType prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; + //portTickType ICACHE_FLASH_ATTR prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; +#endif + +signed portBASE_TYPE ICACHE_FLASH_ATTR +xTaskGenericCreate( pdTASK_CODE pxTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions ) +{ +signed portBASE_TYPE xReturn; +tskTCB * pxNewTCB; + + configASSERT( pxTaskCode ); + configASSERT( ( ( uxPriority & ( ~portPRIVILEGE_BIT ) ) < configMAX_PRIORITIES ) ); + + /* Allocate the memory required by the TCB and stack for the new task, + checking that the allocation was successful. */ + pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer ); + + if( pxNewTCB != NULL ) + { + portSTACK_TYPE *pxTopOfStack; + + #if( portUSING_MPU_WRAPPERS == 1 ) + /* Should the task be created in privileged mode? */ + portBASE_TYPE xRunPrivileged; + if( ( uxPriority & portPRIVILEGE_BIT ) != 0U ) + { + xRunPrivileged = pdTRUE; + } + else + { + xRunPrivileged = pdFALSE; + } + uxPriority &= ~portPRIVILEGE_BIT; + #endif /* portUSING_MPU_WRAPPERS == 1 */ + + /* Calculate the top of stack address. This depends on whether the + stack grows from high memory to low (as per the 80x86) or visa versa. + portSTACK_GROWTH is used to make the result positive or negative as + required by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( unsigned short ) 1 ); + pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */ + + /* Check the alignment of the calculated top of stack is correct. */ + configASSERT( ( ( ( unsigned long ) pxTopOfStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + } + #else /* portSTACK_GROWTH */ + { + pxTopOfStack = pxNewTCB->pxStack; + + /* Check the alignment of the stack buffer is correct. */ + configASSERT( ( ( ( unsigned long ) pxNewTCB->pxStack & ( unsigned long ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + /* If we want to use stack checking on architectures that use + a positive stack growth direction then we also need to store the + other extreme of the stack space. */ + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ); + } + #endif /* portSTACK_GROWTH */ + + /* Setup the newly allocated TCB with the initial state of the task. */ + prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth ); + + /* Initialize the TCB stack to look as if the task was already running, + but had been interrupted by the scheduler. The return address is set + to the start of the task function. Once the stack has been initialised + the top of stack variable is updated. */ + #if( portUSING_MPU_WRAPPERS == 1 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else /* portUSING_MPU_WRAPPERS */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + } + #endif /* portUSING_MPU_WRAPPERS */ + + if( ( void * ) pxCreatedTask != NULL ) + { + /* Pass the TCB out - in an anonymous way. The calling function/ + task can use this as a handle to delete the task later if + required.*/ + *pxCreatedTask = ( xTaskHandle ) pxNewTCB; + } + + /* Ensure interrupts don't access the task lists while they are being + updated. */ + taskENTER_CRITICAL(); + { + uxCurrentNumberOfTasks++; + if( pxCurrentTCB == NULL ) + { + /* There are no other tasks, or all the other tasks are in + the suspended state - make this the current task. */ + pxCurrentTCB = pxNewTCB; + + if( uxCurrentNumberOfTasks == ( unsigned portBASE_TYPE ) 1 ) + { + /* This is the first task to be created so do the preliminary + initialisation required. We will not recover if this call + fails, but we will report the failure. */ + prvInitialiseTaskLists(); + } + } + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ + if( xSchedulerRunning == pdFALSE ) + { + if( pxCurrentTCB->uxPriority <= uxPriority ) + { + pxCurrentTCB = pxNewTCB; + } + } + } + + uxTaskNumber++; + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif /* configUSE_TRACE_FACILITY */ + traceTASK_CREATE( pxNewTCB ); + + prvAddTaskToReadyList( pxNewTCB ); + + xReturn = pdPASS; + portSETUP_TCB( pxNewTCB ); + } + taskEXIT_CRITICAL(); + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + traceTASK_CREATE_FAILED(); + } + + if( xReturn == pdPASS ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* If the created task is of a higher priority than the current task + then it should run now. */ + if( pxCurrentTCB->uxPriority < uxPriority ) + { + portYIELD_WITHIN_API(); + } + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + void ICACHE_FLASH_ATTR + vTaskDelete( xTaskHandle xTaskToDelete ) + { + tskTCB *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then we are deleting ourselves. */ + pxTCB = prvGetTCBFromHandle( xTaskToDelete ); + + /* Remove task from the ready list and place in the termination list. + This will stop the task from be scheduled. The idle task will check + the termination list and free up any memory allocated by the + scheduler for the TCB and stack. */ + if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + + vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) ); + + /* Increment the ucTasksDeleted variable so the idle task knows + there is a task that has been deleted and that it should therefore + check the xTasksWaitingTermination list. */ + ++uxTasksDeleted; + + /* Increment the uxTaskNumberVariable also so kernel aware debuggers + can detect that the task lists need re-generating. */ + uxTaskNumber++; + + traceTASK_DELETE( pxTCB ); + } + taskEXIT_CRITICAL(); + + /* Force a reschedule if we have just deleted the current task. */ + if( xSchedulerRunning != pdFALSE ) + { + if( pxTCB == pxCurrentTCB ) + { + portYIELD_WITHIN_API(); + } + } + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + + void ICACHE_FLASH_ATTR + vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement ) + { + portTickType xTimeToWake; + portBASE_TYPE xAlreadyYielded, xShouldDelay = pdFALSE; + + configASSERT( pxPreviousWakeTime ); + configASSERT( ( xTimeIncrement > 0U ) ); + + vTaskSuspendAll(); + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const portTickType xConstTickCount = xTickCount; + + /* Generate the tick time at which the task wants to wake. */ + xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; + + if( xConstTickCount < *pxPreviousWakeTime ) + { + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + } + else + { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + } + + /* Update the wake time ready for the next call. */ + *pxPreviousWakeTime = xTimeToWake; + + if( xShouldDelay != pdFALSE ) + { + traceTASK_DELAY_UNTIL(); + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) + { + /* The current task must be in a ready list, so there is + no need to check, and the port reset macro can be called + directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + } + + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + } + +#endif /* INCLUDE_vTaskDelayUntil */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + + void ICACHE_FLASH_ATTR + vTaskDelay( portTickType xTicksToDelay ) + { + portTickType xTimeToWake; + signed portBASE_TYPE xAlreadyYielded = pdFALSE; + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( portTickType ) 0U ) + { + vTaskSuspendAll(); + { + traceTASK_DELAY(); + + /* A task that is removed from the event list while the + scheduler is suspended will not get placed in the ready + list or removed from the blocked list until the scheduler + is resumed. + + This task cannot be in an event list as it is the currently + executing task. */ + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) + { + /* The current task must be in a ready list, so there is + no need to check, and the port reset macro can be called + directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + } + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + xAlreadyYielded = xTaskResumeAll(); + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + } + +#endif /* INCLUDE_vTaskDelay */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + + eTaskState ICACHE_FLASH_ATTR + eTaskGetState( xTaskHandle xTask ) + { + eTaskState eReturn; + xList *pxStateList; + const tskTCB * const pxTCB = ( tskTCB * ) xTask; + + if( pxTCB == pxCurrentTCB ) + { + /* The task calling this function is querying its own state. */ + eReturn = eRunning; + } + else + { + taskENTER_CRITICAL(); + { + pxStateList = ( xList * ) listLIST_ITEM_CONTAINER( &( pxTCB->xGenericListItem ) ); + } + taskEXIT_CRITICAL(); + + if( ( pxStateList == pxDelayedTaskList ) || ( pxStateList == pxOverflowDelayedTaskList ) ) + { + /* The task being queried is referenced from one of the Blocked + lists. */ + eReturn = eBlocked; + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + else if( pxStateList == &xSuspendedTaskList ) + { + /* The task being queried is referenced from the suspended + list. */ + eReturn = eSuspended; + } + #endif + + #if ( INCLUDE_vTaskDelete == 1 ) + else if( pxStateList == &xTasksWaitingTermination ) + { + /* The task being queried is referenced from the deleted + tasks list. */ + eReturn = eDeleted; + } + #endif + + else + { + /* If the task is not in any other state, it must be in the + Ready (including pending ready) state. */ + eReturn = eReady; + } + } + + return eReturn; + } + +#endif /* INCLUDE_eTaskGetState */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + unsigned portBASE_TYPE ICACHE_FLASH_ATTR + uxTaskPriorityGet( xTaskHandle xTask ) + { + tskTCB *pxTCB; + unsigned portBASE_TYPE uxReturn; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then we are changing the + priority of the calling function. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + taskEXIT_CRITICAL(); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void ICACHE_FLASH_ATTR + vTaskPrioritySet( xTaskHandle xTask, unsigned portBASE_TYPE uxNewPriority ) + { + tskTCB *pxTCB; + unsigned portBASE_TYPE uxCurrentBasePriority, uxPriorityUsedOnEntry; + portBASE_TYPE xYieldRequired = pdFALSE; + + configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) ); + + /* Ensure the new priority is valid. */ + if( uxNewPriority >= ( unsigned portBASE_TYPE ) configMAX_PRIORITIES ) + { + uxNewPriority = ( unsigned portBASE_TYPE ) configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U; + } + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the calling + task that is being changed. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); + + #if ( configUSE_MUTEXES == 1 ) + { + uxCurrentBasePriority = pxTCB->uxBasePriority; + } + #else + { + uxCurrentBasePriority = pxTCB->uxPriority; + } + #endif + + if( uxCurrentBasePriority != uxNewPriority ) + { + /* The priority change may have readied a task of higher + priority than the calling task. */ + if( uxNewPriority > uxCurrentBasePriority ) + { + if( pxTCB != pxCurrentTCB ) + { + /* The priority of a task other than the currently + running task is being raised. Is the priority being + raised above that of the running task? */ + if( uxNewPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + } + else + { + /* The priority of the running task is being raised, + but the running task must already be the highest + priority task able to run so no yield is required. */ + } + } + else if( pxTCB == pxCurrentTCB ) + { + /* Setting the priority of the running task down means + there may now be another task of higher priority that + is ready to execute. */ + xYieldRequired = pdTRUE; + } + else + { + /* Setting the priority of any other task down does not + require a yield as the running task must be above the + new priority of the task being modified. */ + } + + /* Remember the ready list the task might be referenced from + before its uxPriority member is changed so the + taskRESET_READY_PRIORITY() macro can function correctly. */ + uxPriorityUsedOnEntry = pxTCB->uxPriority; + + #if ( configUSE_MUTEXES == 1 ) + { + /* Only change the priority being used if the task is not + currently using an inherited priority. */ + if( pxTCB->uxBasePriority == pxTCB->uxPriority ) + { + pxTCB->uxPriority = uxNewPriority; + } + + /* The base priority gets set whatever. */ + pxTCB->uxBasePriority = uxNewPriority; + } + #else + { + pxTCB->uxPriority = uxNewPriority; + } + #endif + + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( portTickType ) configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* If the task is in the blocked or suspended list we need do + nothing more than change it's priority variable. However, if + the task is in a ready list it needs to be removed and placed + in the list appropriate to its new priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE ) + { + /* The task is currently in its ready list - remove before adding + it to it's new ready list. As we are in a critical section we + can do this even if the scheduler is suspended. */ + if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) + { + /* It is known that the task is in its ready list so + there is no need to check again and the port level + reset macro can be called directly. */ + portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority ); + } + prvAddTaskToReadyList( pxTCB ); + } + + if( xYieldRequired == pdTRUE ) + { + portYIELD_WITHIN_API(); + } + + /* Remove compiler warning about unused variables when the port + optimised task selection is not being used. */ + ( void ) uxPriorityUsedOnEntry; + } + } + taskEXIT_CRITICAL(); + } + +#endif /* INCLUDE_vTaskPrioritySet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void ICACHE_FLASH_ATTR + vTaskSuspend( xTaskHandle xTaskToSuspend ) + { + tskTCB *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the running task that is + being suspended. */ + pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the suspended list. */ + if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + + vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ); + } + taskEXIT_CRITICAL(); + + if( pxTCB == pxCurrentTCB ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* The current task has just been suspended. */ + portYIELD_WITHIN_API(); + } + else + { + /* The scheduler is not running, but the task that was pointed + to by pxCurrentTCB has just been suspended and pxCurrentTCB + must be adjusted to point to a different task. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) + { + /* No other tasks are ready, so set pxCurrentTCB back to + NULL so when the next task is created pxCurrentTCB will + be set to point to it no matter what its relative priority + is. */ + pxCurrentTCB = NULL; + } + else + { + vTaskSwitchContext(); + } + } + } + } + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + signed portBASE_TYPE ICACHE_FLASH_ATTR + xTaskIsTaskSuspended( xTaskHandle xTask ) + { + portBASE_TYPE xReturn = pdFALSE; + const tskTCB * const pxTCB = ( tskTCB * ) xTask; + + /* It does not make sense to check if the calling task is suspended. */ + configASSERT( xTask ); + + /* Is the task we are attempting to resume actually in the + suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE ) + { + /* Is it in the suspended list because it is in the + Suspended state? It is possible to be in the suspended + list because it is blocked on a task with no timeout + specified. */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) + { + xReturn = pdTRUE; + } + } + } + + return xReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void ICACHE_FLASH_ATTR + vTaskResume( xTaskHandle xTaskToResume ) + { + tskTCB * const pxTCB = ( tskTCB * ) xTaskToResume; + + /* It does not make sense to resume the calling task. */ + configASSERT( xTaskToResume ); + + /* The parameter cannot be NULL as it is impossible to resume the + currently executing task. */ + if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) + { + taskENTER_CRITICAL(); + { + if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + { + traceTASK_RESUME( pxTCB ); + + /* As we are in a critical section we can access the ready + lists even if the scheduler is suspended. */ + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* We may have just resumed a higher priority task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* This yield may not cause the task just resumed to run, but + will leave the lists in the correct state for the next yield. */ + portYIELD_WITHIN_API(); + } + } + } + taskEXIT_CRITICAL(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ + +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + portBASE_TYPE ICACHE_FLASH_ATTR + xTaskResumeFromISR( xTaskHandle xTaskToResume ) + { + portBASE_TYPE xYieldRequired = pdFALSE; + tskTCB * const pxTCB = ( tskTCB * ) xTaskToResume; + unsigned portBASE_TYPE uxSavedInterruptStatus; + + configASSERT( xTaskToResume ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + +// uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + portSET_INTERRUPT_MASK_FROM_ISR(); + + { + if( xTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + xYieldRequired = ( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ); + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed, at which point a + yield will be performed if necessary. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xYieldRequired; + } + +#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ +/*-----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vTaskStartScheduler( void ) +{ +portBASE_TYPE xReturn; + + /* Add the idle task at the lowest priority. */ + #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + { + /* Create the idle task, storing its handle in xIdleTaskHandle so it can + be returned by the xTaskGetIdleTaskHandle() function. */ + xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + } + #else + { + /* Create the idle task without storing its handle. */ + xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + } + #endif /* INCLUDE_xTaskGetIdleTaskHandle */ + + #if ( configUSE_TIMERS == 1 ) + { + if( xReturn == pdPASS ) + { + xReturn = xTimerCreateTimerTask(); + } + } + #endif /* configUSE_TIMERS */ + + if( xReturn == pdPASS ) + { + /* Interrupts are turned off here, to ensure a tick does not occur + before or during the call to xPortStartScheduler(). The stacks of + the created tasks contain a status word with interrupts switched on + so interrupts will automatically get re-enabled when the first task + starts to run. + + STEPPING THROUGH HERE USING A DEBUGGER CAN CAUSE BIG PROBLEMS IF THE + DEBUGGER ALLOWS INTERRUPTS TO BE PROCESSED. */ + //portDISABLE_INTERRUPTS(); +//PortDisableInt_NoNest(); + + xSchedulerRunning = pdTRUE; + xTickCount = ( portTickType ) 0U; + + /* If configGENERATE_RUN_TIME_STATS is defined then the following + macro must be defined to configure the timer/counter used to generate + the run time counter time base. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + /* Setting up the timer tick is hardware specific and thus in the + portable interface. */ + if( xPortStartScheduler() != pdFALSE ) + { + /* Should not reach here as if the scheduler is running the + function will not return. */ + } + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } + else + { + /* This line will only be reached if the kernel could not be started, + because there was not enough FreeRTOS heap to create the idle task + or the timer task. */ + configASSERT( xReturn ); + } +} +/*-----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + routine so the original ISRs can be restored if necessary. The port + layer must ensure interrupts enable bit is left in the correct state. */ + + //portDISABLE_INTERRUPTS(); +PortDisableInt_NoNest(); + xSchedulerRunning = pdFALSE; + vPortEndScheduler(); +} +/*----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + portBASE_TYPE. */ + ++uxSchedulerSuspended; +} +/*----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE != 0 ) + + //static portTickType ICACHE_FLASH_ATTR + portTickType ICACHE_FLASH_ATTR prvGetExpectedIdleTime( void ) + { + portTickType xReturn; + + if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY ) + { + xReturn = 0; + } + else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 ) + { + /* There are other idle priority tasks in the ready state. If + time slicing is used then the very next tick interrupt must be + processed. */ + xReturn = 0; + } + else + { + xReturn = xNextTaskUnblockTime - xTickCount; + } + + return xReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +signed portBASE_TYPE ICACHE_FLASH_ATTR +xTaskResumeAll( void ) +{ +tskTCB *pxTCB; +portBASE_TYPE xAlreadyYielded = pdFALSE; +portBASE_TYPE xYieldRequired = pdFALSE; + + /* If uxSchedulerSuspended is zero then this function does not match a + previous call to vTaskSuspendAll(). */ + configASSERT( uxSchedulerSuspended ); + + /* It is possible that an ISR caused a task to be removed from an event + list while the scheduler was suspended. If this was the case then the + removed task will have been added to the xPendingReadyList. Once the + scheduler has been resumed it is safe to move all the pending ready + tasks from this list into their appropriate ready list. */ + taskENTER_CRITICAL(); + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + if( uxCurrentNumberOfTasks > ( unsigned portBASE_TYPE ) 0U ) + { + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE ) + { + pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* If we have moved a task that has a priority higher than + the current task then we should yield. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + } + + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does not + slip, and that any delayed tasks are resumed at the correct time. */ + if( uxPendedTicks > ( unsigned portBASE_TYPE ) 0U ) + { + while( uxPendedTicks > ( unsigned portBASE_TYPE ) 0U ) + { + if( xTaskIncrementTick() != pdFALSE ) + { + xYieldRequired = pdTRUE; + } + --uxPendedTicks; + } + } + + if( ( xYieldRequired == pdTRUE ) || ( xYieldPending == pdTRUE ) ) + { + xAlreadyYielded = pdTRUE; + xYieldPending = pdFALSE; + portYIELD_WITHIN_API(); + } + } + } + } + taskEXIT_CRITICAL(); + + return xAlreadyYielded; +} +/*-----------------------------------------------------------*/ + +portTickType ICACHE_FLASH_ATTR +xTaskGetTickCount( void ) +{ +portTickType xTicks; + + /* Critical section required if running on a 16 bit processor. */ + taskENTER_CRITICAL(); + { + xTicks = xTickCount; + } + taskEXIT_CRITICAL(); + + return xTicks; +} +/*-----------------------------------------------------------*/ + +portTickType ICACHE_FLASH_ATTR +xTaskGetTickCountFromISR( void ) +{ +portTickType xReturn; +unsigned portBASE_TYPE uxSavedInterruptStatus; + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are keep permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + +// uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + portSET_INTERRUPT_MASK_FROM_ISR(); + + xReturn = xTickCount; + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +unsigned portBASE_TYPE ICACHE_FLASH_ATTR +uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + portBASE_TYPE. */ + return uxCurrentNumberOfTasks; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_pcTaskGetTaskName == 1 ) + + signed char * ICACHE_FLASH_ATTR + pcTaskGetTaskName( xTaskHandle xTaskToQuery ) + { + tskTCB *pxTCB; + + /* If null is passed in here then the name of the calling task is being queried. */ + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + configASSERT( pxTCB ); + return &( pxTCB->pcTaskName[ 0 ] ); + } + +#endif /* INCLUDE_pcTaskGetTaskName */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + unsigned portBASE_TYPE ICACHE_FLASH_ATTR + uxTaskGetSystemState( xTaskStatusType *pxTaskStatusArray, unsigned portBASE_TYPE uxArraySize, unsigned long *pulTotalRunTime ) + { + unsigned portBASE_TYPE uxTask = 0, uxQueue = configMAX_PRIORITIES; + + vTaskSuspendAll(); + { + /* Is there a space in the array for each task in the system? */ + if( uxArraySize >= uxCurrentNumberOfTasks ) + { + /* Fill in an xTaskStatusType structure with information on each + task in the Ready state. */ + do + { + uxQueue--; + uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady ); + + } while( uxQueue > ( unsigned portBASE_TYPE ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Fill in an xTaskStatusType structure with information on each + task in the Blocked state. */ + uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( xList * ) pxDelayedTaskList, eBlocked ); + uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( xList * ) pxOverflowDelayedTaskList, eBlocked ); + + #if( INCLUDE_vTaskDelete == 1 ) + { + /* Fill in an xTaskStatusType structure with information on + each task that has been deleted but not yet cleaned up. */ + uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted ); + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* Fill in an xTaskStatusType structure with information on + each task in the Suspended state. */ + uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended ); + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1) + { + if( pulTotalRunTime != NULL ) + { + *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + } + } + #else + { + if( pulTotalRunTime != NULL ) + { + *pulTotalRunTime = 0; + } + } + #endif + } + } + ( void ) xTaskResumeAll(); + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + xTaskHandle ICACHE_FLASH_ATTR + xTaskGetIdleTaskHandle( void ) + { + /* If xTaskGetIdleTaskHandle() is called before the scheduler has been + started, then xIdleTaskHandle will be NULL. */ + configASSERT( ( xIdleTaskHandle != NULL ) ); + return xIdleTaskHandle; + } + +#endif /* INCLUDE_xTaskGetIdleTaskHandle */ +/*----------------------------------------------------------*/ + +/* This conditional compilation should use inequality to 0, not equality to 1. +This is to ensure vTaskStepTick() is available when user defined low power mode +implementations require configUSE_TICKLESS_IDLE to be set to a value other than +1. */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + void ICACHE_FLASH_ATTR + vTaskStepTick( portTickType xTicksToJump ) + { + /* Correct the tick count value after a period during which the tick + was suppressed. Note this does *not* call the tick hook function for + each stepped tick. */ + configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); + xTickCount += xTicksToJump; + traceINCREASE_TICK_COUNT( xTicksToJump ); + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +portBASE_TYPE +xTaskIncrementTick( void ) +{ +tskTCB * pxTCB; +portTickType xItemValue; +portBASE_TYPE xSwitchRequired = pdFALSE; + + /* Called by the portable layer each time a tick interrupt occurs. + Increments the tick then checks to see if the new tick value will cause any + tasks to be unblocked. */ + traceTASK_INCREMENT_TICK( xTickCount ); + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + /* Increment the RTOS tick, switching the delayed and overflowed + delayed lists if it wraps to 0. */ + ++xTickCount; + + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const portTickType xConstTickCount = xTickCount; + + if( xConstTickCount == ( portTickType ) 0U ) + { + taskSWITCH_DELAYED_LISTS(); + } + + /* See if this tick has made a timeout expire. Tasks are stored in the + queue in the order of their wake time - meaning once one tasks has been + found whose block time has not expired there is no need not look any + further down the list. */ + if( xConstTickCount >= xNextTaskUnblockTime ) + { + for( ;; ) + { + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The delayed list is empty. Set xNextTaskUnblockTime to + the maximum possible value so it is extremely unlikely that + the if( xTickCount >= xNextTaskUnblockTime ) test will pass + next time through. */ + xNextTaskUnblockTime = portMAX_DELAY; + break; + } + else + { + /* The delayed list is not empty, get the value of the item + at the head of the delayed list. This is the time at which + the task at the head of the delayed list must be removed + from the Blocked state. */ + pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); + xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); + + if( xConstTickCount < xItemValue ) + { + /* It is not time to unblock this item yet, but the item + value is the time at which the task at the head of the + blocked list must be removed from the Blocked state - + so record the item value in xNextTaskUnblockTime. */ + xNextTaskUnblockTime = xItemValue; + break; + } + + /* It is time to remove the item from the Blocked state. */ + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + + /* Is the task waiting on an event also? If so remove it + from the event list. */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + + /* Place the unblocked task into the appropriate ready + list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate context + switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should only + be performed if the unblocked task has a priority that + is equal to or higher than the currently executing + task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xSwitchRequired = pdTRUE; + } + } + #endif /* configUSE_PREEMPTION */ + } + } + } + } + + /* Tasks of equal priority to the currently running task will share + processing time (time slice) if preemption is on, and the application + writer has not explicitly turned time slicing off. */ + #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) + { + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( unsigned portBASE_TYPE ) 1 ) + { + xSwitchRequired = pdTRUE; + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ + } + else + { + ++uxPendedTicks; + + /* The tick hook gets called at regular intervals, even if the + scheduler is locked. */ + #if ( configUSE_TICK_HOOK == 1 ) + { + vApplicationTickHook(); + } + #endif + } + + #if ( configUSE_TICK_HOOK == 1 ) + { + /* Guard against the tick hook being called when the missed tick + count is being unwound (when the scheduler is being unlocked). */ + if( uxPendedTicks == ( unsigned portBASE_TYPE ) 0U ) + { + vApplicationTickHook(); + } + } + #endif /* configUSE_TICK_HOOK */ + + return xSwitchRequired; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void ICACHE_FLASH_ATTR + vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxHookFunction ) + { + tskTCB *xTCB; + + /* If xTask is NULL then we are setting our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( tskTCB * ) pxCurrentTCB; + } + else + { + xTCB = ( tskTCB * ) xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + xTCB->pxTaskTag = pxHookFunction; + taskEXIT_CRITICAL(); + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + pdTASK_HOOK_CODE ICACHE_FLASH_ATTR + xTaskGetApplicationTaskTag( xTaskHandle xTask ) + { + tskTCB *xTCB; + pdTASK_HOOK_CODE xReturn; + + /* If xTask is NULL then we are setting our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( tskTCB * ) pxCurrentTCB; + } + else + { + xTCB = ( tskTCB * ) xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + xReturn = xTCB->pxTaskTag; + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + portBASE_TYPE ICACHE_FLASH_ATTR + xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter ) + { + tskTCB *xTCB; + portBASE_TYPE xReturn; + + /* If xTask is NULL then we are calling our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( tskTCB * ) pxCurrentTCB; + } + else + { + xTCB = ( tskTCB * ) xTask; + } + + if( xTCB->pxTaskTag != NULL ) + { + xReturn = xTCB->pxTaskTag( pvParameter ); + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +void +vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( unsigned portBASE_TYPE ) pdFALSE ) + { + /* The scheduler is currently suspended - do not allow a context + switch. */ + xYieldPending = pdTRUE; + } + else + { + traceTASK_SWITCHED_OUT(); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + #else + ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + /* Add the amount of time the task has been running to the + accumulated time so far. The time the task started running was + stored in ulTaskSwitchedInTime. Note that there is no overflow + protection here so count values are only valid until the timer + overflows. The guard against negative values is to protect + against suspect run time stat counter implementations - which + are provided by the application, not the kernel. */ + if( ulTotalRunTime > ulTaskSwitchedInTime ) + { + pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); + } + ulTaskSwitchedInTime = ulTotalRunTime; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + taskFIRST_CHECK_FOR_STACK_OVERFLOW(); + taskSECOND_CHECK_FOR_STACK_OVERFLOW(); + + taskSELECT_HIGHEST_PRIORITY_TASK(); + + traceTASK_SWITCHED_IN(); + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to this task. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + } +} +/*-----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vTaskPlaceOnEventList( xList * const pxEventList, portTickType xTicksToWait ) +{ +portTickType xTimeToWake; + + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED. */ + + /* Place the event list item of the TCB in the appropriate event list. + This is placed in the list in priority order so the highest priority task + is the first to be woken by the event. */ + vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + /* We must remove ourselves from the ready list before adding ourselves + to the blocked list as the same list item is used for both lists. We have + exclusive access to the ready lists as the scheduler is locked. */ + if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) + { + /* The current task must be in a ready list, so there is no need to + check, and the port reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( xTicksToWait == portMAX_DELAY ) + { + /* Add ourselves to the suspended task list instead of a delayed task + list to ensure we are not woken by a timing event. We will block + indefinitely. */ + vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter. */ + xTimeToWake = xTickCount + xTicksToWait; + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + } + #else /* INCLUDE_vTaskSuspend */ + { + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter. */ + xTimeToWake = xTickCount + xTicksToWait; + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + #endif /* INCLUDE_vTaskSuspend */ +} +/*-----------------------------------------------------------*/ + +#if configUSE_TIMERS == 1 + + void ICACHE_FLASH_ATTR + vTaskPlaceOnEventListRestricted( xList * const pxEventList, portTickType xTicksToWait ) + { + portTickType xTimeToWake; + + configASSERT( pxEventList ); + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements - + it should be called from a critical section. */ + + + /* Place the event list item of the TCB in the appropriate event list. + In this case it is assume that this is the only task that is going to + be waiting on this event list, so the faster vListInsertEnd() function + can be used in place of vListInsert. */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + /* We must remove this task from the ready list before adding it to the + blocked list as the same list item is used for both lists. This + function is called form a critical section. */ + if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) + { + /* The current task must be in a ready list, so there is no need to + check, and the port reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + } + + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter. */ + xTimeToWake = xTickCount + xTicksToWait; + + traceTASK_DELAY_UNTIL(); + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +signed portBASE_TYPE ICACHE_FLASH_ATTR +xTaskRemoveFromEventList( const xList * const pxEventList ) +{ +tskTCB *pxUnblockedTCB; +portBASE_TYPE xReturn; + + /* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED. It can also be called from within an ISR. */ + + /* The event list is sorted in priority order, so we can remove the + first in the list, remove the TCB from the delayed list, and add + it to the ready list. + + If an event is for a queue that is locked then this function will never + get called - the lock count on the queue will get modified instead. This + means we can always expect exclusive access to the event list here. + + This function assumes that a check has already been made to ensure that + pxEventList is not empty. */ + pxUnblockedTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); + + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + ( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + } + else + { + /* We cannot access the delayed or ready lists, so will hold this + task pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + } + + if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has + a higher priority than the calling task. This allows + the calling task to know if it should force a context + switch now. */ + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vTaskSetTimeOutState( xTimeOutType * const pxTimeOut ) +{ + configASSERT( pxTimeOut ); + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE ICACHE_FLASH_ATTR +xTaskCheckForTimeOut( xTimeOutType * const pxTimeOut, portTickType * const pxTicksToWait ) +{ +portBASE_TYPE xReturn; + + configASSERT( pxTimeOut ); + configASSERT( pxTicksToWait ); + + taskENTER_CRITICAL(); + { + /* Minor optimisation. The tick count cannot change in this block. */ + const portTickType xConstTickCount = xTickCount; + + #if ( INCLUDE_vTaskSuspend == 1 ) + /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is + the maximum block time then the task should block indefinitely, and + therefore never time out. */ + if( *pxTicksToWait == portMAX_DELAY ) + { + xReturn = pdFALSE; + } + else /* We are not blocking indefinitely, perform the checks below. */ + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */ + { + /* The tick count is greater than the time at which vTaskSetTimeout() + was called, but has also overflowed since vTaskSetTimeOut() was called. + It must have wrapped all the way around and gone past us again. This + passed since vTaskSetTimeout() was called. */ + xReturn = pdTRUE; + } + else if( ( xConstTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait ) + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering ); + vTaskSetTimeOutState( pxTimeOut ); + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void ICACHE_FLASH_ATTR +vTaskMissedYield( void ) +{ + xYieldPending = pdTRUE; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + unsigned portBASE_TYPE ICACHE_FLASH_ATTR + uxTaskGetTaskNumber( xTaskHandle xTask ) + { + unsigned portBASE_TYPE uxReturn; + tskTCB *pxTCB; + + if( xTask != NULL ) + { + pxTCB = ( tskTCB * ) xTask; + uxReturn = pxTCB->uxTaskNumber; + } + else + { + uxReturn = 0U; + } + + return uxReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void ICACHE_FLASH_ATTR + vTaskSetTaskNumber( xTaskHandle xTask, unsigned portBASE_TYPE uxHandle ) + { + tskTCB *pxTCB; + + if( xTask != NULL ) + { + pxTCB = ( tskTCB * ) xTask; + pxTCB->uxTaskNumber = uxHandle; + } + } + +#endif /* configUSE_TRACE_FACILITY */ + +/* + * ----------------------------------------------------------- + * The Idle task. + * ---------------------------------------------------------- + * + * The portTASK_FUNCTION() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static ICACHE_FLASH_ATTR +portTASK_FUNCTION( prvIdleTask, pvParameters ) +{ + /* Stop warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* See if any tasks have been deleted. */ + prvCheckTasksWaitingTermination(); + + #if ( configUSE_PREEMPTION == 0 ) + { + /* If we are not using preemption we keep forcing a task switch to + see if any other task has become available. If we are using + preemption we don't need to do this as any task becoming available + will automatically get the processor anyway. */ + taskYIELD(); + } + #endif /* configUSE_PREEMPTION */ + + #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) + { + /* When using preemption tasks of equal priority will be + timesliced. If a task that is sharing the idle priority is ready + to run then the idle task should yield before the end of the + timeslice. + + A critical region is not required here as we are just reading from + the list, and an occasional incorrect value will not matter. If + the ready list at the idle priority contains more than one task + then a task other than the idle task is ready to execute. */ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( unsigned portBASE_TYPE ) 1 ) + { + taskYIELD(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */ + + #if ( configUSE_IDLE_HOOK == 1 ) + { + extern void vApplicationIdleHook( void ); + + /* Call the user defined function from within the idle task. This + allows the application designer to add background functionality + without the overhead of a separate task. + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, + CALL A FUNCTION THAT MIGHT BLOCK. */ + vApplicationIdleHook(); + } + #endif /* configUSE_IDLE_HOOK */ + + /* This conditional compilation should use inequality to 0, not equality + to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when + user defined low power mode implementations require + configUSE_TICKLESS_IDLE to be set to a value other than 1. */ + + //#if ( configUSE_TICKLESS_IDLE != 0 ) + #if 0 + { + portTickType xExpectedIdleTime; + + /* It is not desirable to suspend then resume the scheduler on + each iteration of the idle task. Therefore, a preliminary + test of the expected idle time is performed without the + scheduler suspended. The result here is not necessarily + valid. */ + xExpectedIdleTime = prvGetExpectedIdleTime(); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + vTaskSuspendAll(); + { + /* Now the scheduler is suspended, the expected idle + time can be sampled again, and this time its value can + be used. */ + configASSERT( xNextTaskUnblockTime >= xTickCount ); + xExpectedIdleTime = prvGetExpectedIdleTime(); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + traceLOW_POWER_IDLE_BEGIN(); + portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); + traceLOW_POWER_IDLE_END(); + } + } + ( void ) xTaskResumeAll(); + } + } + #endif /* configUSE_TICKLESS_IDLE */ + } +} +/*-----------------------------------------------------------*/ + +#if configUSE_TICKLESS_IDLE != 0 + + eSleepModeStatus ICACHE_FLASH_ATTR + eTaskConfirmSleepModeStatus( void ) + { + eSleepModeStatus eReturn = eStandardSleep; + + if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 ) + { + /* A task was made ready while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else if( xYieldPending != pdFALSE ) + { + /* A yield was pended while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else + { + #if configUSE_TIMERS == 0 + { + /* The idle task exists in addition to the application tasks. */ + const unsigned portBASE_TYPE uxNonApplicationTasks = 1; + + /* If timers are not being used and all the tasks are in the + suspended list (which might mean they have an infinite block + time rather than actually being suspended) then it is safe to + turn all clocks off and just wait for external interrupts. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) ) + { + eReturn = eNoTasksWaitingTimeout; + } + } + #endif /* configUSE_TIMERS */ + } + + return eReturn; + } +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvInitialiseTCBVariables( tskTCB *pxTCB, const signed char * const pcName, unsigned portBASE_TYPE uxPriority, const xMemoryRegion * const xRegions, unsigned short usStackDepth ) +{ +unsigned portBASE_TYPE x; + + /* Store the task name in the TCB. */ + for( x = ( unsigned portBASE_TYPE ) 0; x < ( unsigned portBASE_TYPE ) configMAX_TASK_NAME_LEN; x++ ) + { + pxTCB->pcTaskName[ x ] = pcName[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + configMAX_TASK_NAME_LEN characters just in case the memory after the + string is not accessible (extremely unlikely). */ + if( pcName[ x ] == 0x00 ) + { + break; + } + } + + /* Ensure the name string is terminated in the case that the string length + was greater or equal to configMAX_TASK_NAME_LEN. */ + pxTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = ( signed char ) '\0'; + + /* This is used as an array index so must ensure it's not too large. First + remove the privilege bit if one is present. */ + if( uxPriority >= ( unsigned portBASE_TYPE ) configMAX_PRIORITIES ) + { + uxPriority = ( unsigned portBASE_TYPE ) configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U; + } + + pxTCB->uxPriority = uxPriority; + #if ( configUSE_MUTEXES == 1 ) + { + pxTCB->uxBasePriority = uxPriority; + } + #endif /* configUSE_MUTEXES */ + + vListInitialiseItem( &( pxTCB->xGenericListItem ) ); + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + + /* Set the pxTCB as a link back from the xListItem. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( portTickType ) configMAX_PRIORITIES - ( portTickType ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + { + pxTCB->uxCriticalNesting = ( unsigned portBASE_TYPE ) 0U; + } + #endif /* portCRITICAL_NESTING_IN_TCB */ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + { + pxTCB->pxTaskTag = NULL; + } + #endif /* configUSE_APPLICATION_TASK_TAG */ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTCB->ulRunTimeCounter = 0UL; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth ); + } + #else /* portUSING_MPU_WRAPPERS */ + { + ( void ) xRegions; + ( void ) usStackDepth; + } + #endif /* portUSING_MPU_WRAPPERS */ + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Initialise this task's Newlib reent structure. */ + _REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ +} +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + void ICACHE_FLASH_ATTR + vTaskAllocateMPURegions( xTaskHandle xTaskToModify, const xMemoryRegion * const xRegions ) + { + tskTCB *pxTCB; + + /* If null is passed in here then we are deleting ourselves. */ + pxTCB = prvGetTCBFromHandle( xTaskToModify ); + + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvInitialiseTaskLists( void ) +{ +unsigned portBASE_TYPE uxPriority; + + for( uxPriority = ( unsigned portBASE_TYPE ) 0U; uxPriority < ( unsigned portBASE_TYPE ) configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) ); + } + + vListInitialise( &xDelayedTaskList1 ); + vListInitialise( &xDelayedTaskList2 ); + vListInitialise( &xPendingReadyList ); + + #if ( INCLUDE_vTaskDelete == 1 ) + { + vListInitialise( &xTasksWaitingTermination ); + } + #endif /* INCLUDE_vTaskDelete */ + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( &xSuspendedTaskList ); + } + #endif /* INCLUDE_vTaskSuspend */ + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + pxOverflowDelayedTaskList = &xDelayedTaskList2; +} +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvCheckTasksWaitingTermination( void ) +{ + #if ( INCLUDE_vTaskDelete == 1 ) + { + portBASE_TYPE xListIsEmpty; + + /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called + too often in the idle task. */ + while( uxTasksDeleted > ( unsigned portBASE_TYPE ) 0U ) + { + vTaskSuspendAll(); + xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination ); + ( void ) xTaskResumeAll(); + + if( xListIsEmpty == pdFALSE ) + { + tskTCB *pxTCB; + + taskENTER_CRITICAL(); + { + pxTCB = ( tskTCB * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + --uxCurrentNumberOfTasks; + --uxTasksDeleted; + } + taskEXIT_CRITICAL(); + + prvDeleteTCB( pxTCB ); + } + } + } + #endif /* vTaskDelete */ +} +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvAddCurrentTaskToDelayedList( portTickType xTimeToWake ) +{ + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the current block list. */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) ); + + /* If the task entering the blocked state was placed at the head of the + list of blocked tasks then xNextTaskUnblockTime needs to be updated + too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + } +} +/*-----------------------------------------------------------*/ + +static tskTCB * ICACHE_FLASH_ATTR +prvAllocateTCBAndStack( unsigned short usStackDepth, portSTACK_TYPE *puxStackBuffer ) +{ +tskTCB *pxNewTCB; + + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function. */ + pxNewTCB = ( tskTCB * ) os_malloc( sizeof( tskTCB ) ); + + if( pxNewTCB != NULL ) + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( portSTACK_TYPE * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( portSTACK_TYPE ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + os_free( pxNewTCB ); + pxNewTCB = NULL; + } + else + { + /* Just to help debugging. */ + ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( portSTACK_TYPE ) ); + } + } + + return pxNewTCB; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + static unsigned portBASE_TYPE ICACHE_FLASH_ATTR + prvListTaskWithinSingleList( xTaskStatusType *pxTaskStatusArray, xList *pxList, eTaskState eState ) + { + volatile tskTCB *pxNextTCB, *pxFirstTCB; + unsigned portBASE_TYPE uxTask = 0; + + if( listCURRENT_LIST_LENGTH( pxList ) > ( unsigned portBASE_TYPE ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + + /* Populate an xTaskStatusType structure within the + pxTaskStatusArray array for each task that is referenced from + pxList. See the definition of xTaskStatusType in task.h for the + meaning of each xTaskStatusType structure member. */ + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + + pxTaskStatusArray[ uxTask ].xHandle = ( xTaskHandle ) pxNextTCB; + pxTaskStatusArray[ uxTask ].pcTaskName = ( const signed char * ) &( pxNextTCB->pcTaskName [ 0 ] ); + pxTaskStatusArray[ uxTask ].xTaskNumber = pxNextTCB->uxTCBNumber; + pxTaskStatusArray[ uxTask ].eCurrentState = eState; + pxTaskStatusArray[ uxTask ].uxCurrentPriority = pxNextTCB->uxPriority; + + #if ( configUSE_MUTEXES == 1 ) + { + pxTaskStatusArray[ uxTask ].uxBasePriority = pxNextTCB->uxBasePriority; + } + #else + { + pxTaskStatusArray[ uxTask ].uxBasePriority = 0; + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTaskStatusArray[ uxTask ].ulRunTimeCounter = pxNextTCB->ulRunTimeCounter; + } + #else + { + pxTaskStatusArray[ uxTask ].ulRunTimeCounter = 0; + } + #endif + + #if ( portSTACK_GROWTH > 0 ) + { + ppxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxEndOfStack ); + } + #else + { + pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( unsigned char * ) pxNextTCB->pxStack ); + } + #endif + + uxTask++; + + } while( pxNextTCB != pxFirstTCB ); + } + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + + static unsigned short ICACHE_FLASH_ATTR + prvTaskCheckFreeStackSpace( const unsigned char * pucStackByte ) + { + register unsigned short usCount = 0U; + + while( *pucStackByte == tskSTACK_FILL_BYTE ) + { + pucStackByte -= portSTACK_GROWTH; + usCount++; + } + + usCount /= sizeof( portSTACK_TYPE ); + + return usCount; + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + unsigned portBASE_TYPE ICACHE_FLASH_ATTR + uxTaskGetStackHighWaterMark( xTaskHandle xTask ) + { + tskTCB *pxTCB; + unsigned char *pcEndOfStack; + unsigned portBASE_TYPE uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pcEndOfStack = ( unsigned char * ) pxTCB->pxStack; + } + #else + { + pcEndOfStack = ( unsigned char * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = ( unsigned portBASE_TYPE ) prvTaskCheckFreeStackSpace( pcEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + static void ICACHE_FLASH_ATTR + prvDeleteTCB( tskTCB *pxTCB ) + { + /* This call is required specifically for the TriCore port. It must be + above the vPortFree() calls. The call is also used by ports/demos that + want to allocate and clean RAM statically. */ + portCLEAN_UP_TCB( pxTCB ); + + /* Free up the memory allocated by the scheduler for the task. It is up to + the task to free any memory allocated at the application level. */ + vPortFreeAligned( pxTCB->pxStack ); + os_free( pxTCB ); + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + xTaskHandle ICACHE_FLASH_ATTR + xTaskGetCurrentTaskHandle( void ) + { + xTaskHandle xReturn; + + /* A critical section is not required as this is not called from + an interrupt and the current TCB will always be the same for any + individual execution thread. */ + xReturn = pxCurrentTCB; + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + + portBASE_TYPE ICACHE_FLASH_ATTR + xTaskGetSchedulerState( void ) + { + portBASE_TYPE xReturn; + + if( xSchedulerRunning == pdFALSE ) + { + xReturn = taskSCHEDULER_NOT_STARTED; + } + else + { + if( uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE ) + { + xReturn = taskSCHEDULER_RUNNING; + } + else + { + xReturn = taskSCHEDULER_SUSPENDED; + } + } + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void ICACHE_FLASH_ATTR + vTaskPriorityInherit( xTaskHandle const pxMutexHolder ) + { + tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder; + + /* If the mutex was given back by an interrupt while the queue was + locked then the mutex holder might now be NULL. */ + if( pxMutexHolder != NULL ) + { + if( pxTCB->uxPriority < pxCurrentTCB->uxPriority ) + { + /* Adjust the mutex holder state to account for its new priority. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( portTickType ) configMAX_PRIORITIES - ( portTickType ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* If the task being modified is in the ready state it will need to + be moved into a new list. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + + /* Inherit the priority before being moved into the new list. */ + pxTCB->uxPriority = pxCurrentTCB->uxPriority; + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* Just inherit the priority. */ + pxTCB->uxPriority = pxCurrentTCB->uxPriority; + } + + traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority ); + } + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void + vTaskPriorityDisinherit( xTaskHandle const pxMutexHolder ) + { + tskTCB * const pxTCB = ( tskTCB * ) pxMutexHolder; + + if( pxMutexHolder != NULL ) + { + if( pxTCB->uxPriority != pxTCB->uxBasePriority ) + { + /* We must be the running task to be able to give the mutex back. + Remove ourselves from the ready list we currently appear in. */ + if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( unsigned portBASE_TYPE ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + + /* Disinherit the priority before adding the task into the new + ready list. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); + pxTCB->uxPriority = pxTCB->uxBasePriority; + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( portTickType ) configMAX_PRIORITIES - ( portTickType ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + prvAddTaskToReadyList( pxTCB ); + } + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void ICACHE_FLASH_ATTR + vTaskEnterCritical( void ) + { + //portDISABLE_INTERRUPTS(); +PortDisableInt_NoNest(); + if( xSchedulerRunning != pdFALSE ) + { + ( pxCurrentTCB->uxCriticalNesting )++; + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void ICACHE_FLASH_ATTR + vTaskExitCritical( void ) + { + if( xSchedulerRunning != pdFALSE ) + { + if( pxCurrentTCB->uxCriticalNesting > 0U ) + { + ( pxCurrentTCB->uxCriticalNesting )--; + + if( pxCurrentTCB->uxCriticalNesting == 0U ) + { + //portENABLE_INTERRUPTS(); + PortEnableInt_NoNest(); + } + } + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) + + void ICACHE_FLASH_ATTR + vTaskList( signed char *pcWriteBuffer ) + { + xTaskStatusType *pxTaskStatusArray; + volatile unsigned portBASE_TYPE uxArraySize, x; + char cStatus; + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that + * displays task names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that + * might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, + * and limited functionality implementation of sprintf() is provided in + * many of the FreeRTOS/Demo sub-directories in a file called + * printf-stdarg.c (note printf-stdarg.c does not provide a full + * snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskList(). + */ + + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. */ + pxTaskStatusArray = os_malloc( uxCurrentNumberOfTasks * sizeof( xTaskStatusType ) ); + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL ); + + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + switch( pxTaskStatusArray[ x ].eCurrentState ) + { + case eReady: cStatus = tskREADY_CHAR; + break; + + case eBlocked: cStatus = tskBLOCKED_CHAR; + break; + + case eSuspended: cStatus = tskSUSPENDED_CHAR; + break; + + case eDeleted: cStatus = tskDELETED_CHAR; + break; + + default: /* Should not get here, but it is included + to prevent static checking errors. */ + cStatus = 0x00; + break; + } + + sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%c\t%u\t%u\t%u\r\n", pxTaskStatusArray[ x ].pcTaskName, cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); + pcWriteBuffer += strlen( ( char * ) pcWriteBuffer ); + } + + /* Free the array again. */ + os_free( pxTaskStatusArray ); + } + } + +#endif /* configUSE_TRACE_FACILITY */ +/*----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) + + void ICACHE_FLASH_ATTR + vTaskGetRunTimeStats( signed char *pcWriteBuffer ) + { + xTaskStatusType *pxTaskStatusArray; + volatile unsigned portBASE_TYPE uxArraySize, x; + unsigned long ulTotalTime, ulStatsAsPercentage; + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part + * of the uxTaskGetSystemState() output into a human readable table that + * displays the amount of time each task has spent in the Running state + * in both absolute and percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library + * function that might bloat the code size, use a lot of stack, and + * provide different results on different platforms. An alternative, + * tiny, third party, and limited functionality implementation of + * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in + * a file called printf-stdarg.c (note printf-stdarg.c does not provide + * a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskGetRunTimeStats(). + */ + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. */ + pxTaskStatusArray = os_malloc( uxCurrentNumberOfTasks * sizeof( xTaskStatusType ) ); + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime ); + + /* For percentage calculations. */ + ulTotalTime /= 100UL; + + /* Avoid divide by zero errors. */ + if( ulTotalTime > 0 ) + { + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + /* What percentage of the total run time has the task used? + This will always be rounded down to the nearest integer. + ulTotalRunTimeDiv100 has already been divided by 100. */ + ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime; + + if( ulStatsAsPercentage > 0UL ) + { + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ + sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%u\t\t%u%%\r\n", pxTaskStatusArray[ x ].pcTaskName, ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); + } + #endif + } + else + { + /* If the percentage is zero here then the task has + consumed less than 1% of the total run time. */ + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ + sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%u\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); + } + #endif + } + + pcWriteBuffer += strlen( ( char * ) pcWriteBuffer ); + } + } + + /* Free the array again. */ + os_free( pxTaskStatusArray ); + } + } + +#endif /* configGENERATE_RUN_TIME_STATS */ + + + diff --git a/third_party/freertos/timers.c b/third_party/freertos/timers.c index a4722bef..9ca5e2a9 100644 --- a/third_party/freertos/timers.c +++ b/third_party/freertos/timers.c @@ -1,718 +1,718 @@ -/* - FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that has become a de facto standard. * - * * - * Help yourself get started quickly and support the FreeRTOS * - * project by purchasing a FreeRTOS tutorial book, reference * - * manual, or both from: http://www.FreeRTOS.org/Documentation * - * * - * Thank you! * - * * - *************************************************************************** - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - >>! NOTE: The modification to the GPL is included to allow you to distribute - >>! a combined work that includes FreeRTOS without being obliged to provide - >>! the source code for proprietary components outside of the FreeRTOS - >>! kernel. - - FreeRTOS 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. Full license text is available from the following - link: http://www.freertos.org/a00114.html - - 1 tab == 4 spaces! - - *************************************************************************** - * * - * Having a problem? Start by reading the FAQ "My application does * - * not run, what could be wrong?" * - * * - * http://www.FreeRTOS.org/FAQHelp.html * - * * - *************************************************************************** - - http://www.FreeRTOS.org - Documentation, books, training, latest versions, - license and Real Time Engineers Ltd. contact details. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High - Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -/* Standard includes. */ -#include - -/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining -all the API functions to use the MPU wrappers. That should only be done when -task.h is included from an application file. */ -#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/timers.h" - -/* Lint e961 and e750 are suppressed as a MISRA exception justified because the -MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the -header files above, but not in this file, in order to generate the correct -privileged Vs unprivileged linkage and placement. */ -#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ - - -/* This entire source file will be skipped if the application is not configured -to include software timer functionality. This #if is closed at the very bottom -of this file. If you want to include software timer functionality then ensure -configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ -#if ( configUSE_TIMERS == 1 ) - -#ifdef MEMLEAK_DEBUG -static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; -#endif - -/* Misc definitions. */ -#define tmrNO_DELAY ( portTickType ) 0U - -/* The definition of the timers themselves. */ -typedef struct tmrTimerControl -{ - const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ - xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ - portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ - unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */ - void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ - tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */ -} xTIMER; - -/* The definition of messages that can be sent and received on the timer -queue. */ -typedef struct tmrTimerQueueMessage -{ - portBASE_TYPE xMessageID; /*<< The command being sent to the timer service task. */ - portTickType xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ - xTIMER * pxTimer; /*<< The timer to which the command will be applied. */ -} xTIMER_MESSAGE; - -/*lint -e956 A manual analysis and inspection has been used to determine which -static variables must be declared volatile. */ - -/* The list in which active timers are stored. Timers are referenced in expire -time order, with the nearest expiry time at the front of the list. Only the -timer service task is allowed to access xActiveTimerList. */ -PRIVILEGED_DATA static xList xActiveTimerList1; -PRIVILEGED_DATA static xList xActiveTimerList2; -PRIVILEGED_DATA static xList *pxCurrentTimerList; -PRIVILEGED_DATA static xList *pxOverflowTimerList; - -/* A queue that is used to send commands to the timer service task. */ -PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL; - -#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 ) - - PRIVILEGED_DATA static xTaskHandle xTimerTaskHandle = NULL; - -#endif - -/*lint +e956 */ - -/*-----------------------------------------------------------*/ - -/* - * Initialise the infrastructure used by the timer service task if it has not - * been initialised already. - */ -static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; - -/* - * The timer service task (daemon). Timer functionality is controlled by this - * task. Other tasks communicate with the timer service task using the - * xTimerQueue queue. - */ -static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION; - -/* - * Called by the timer service task to interpret and process a command it - * received on the timer queue. - */ -static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; - -/* - * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, - * depending on if the expire time causes a timer counter overflow. - */ -static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION; - -/* - * An active timer has reached its expire time. Reload the timer if it is an - * auto reload timer, then call its callback. - */ -static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION; - -/* - * The tick count has overflowed. Switch the timer lists after ensuring the - * current timer list does not still reference some timers. - */ -static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION; - -/* - * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE - * if a tick count overflow occurred since prvSampleTimeNow() was last called. - */ -static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; - -/* - * If the timer list contains any active timers then return the expire time of - * the timer that will expire first and set *pxListWasEmpty to false. If the - * timer list does not contain any timers then return 0 and set *pxListWasEmpty - * to pdTRUE. - */ -static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) PRIVILEGED_FUNCTION; - -/* - * If a timer has expired, process it. Otherwise, block the timer service task - * until either a timer does expire or a command is received. - */ -static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION; - -/*-----------------------------------------------------------*/ - -portBASE_TYPE ICACHE_FLASH_ATTR -xTimerCreateTimerTask( void ) -{ -portBASE_TYPE xReturn = pdFAIL; - - /* This function is called when the scheduler is started if - configUSE_TIMERS is set to 1. Check that the infrastructure used by the - timer service task has been created/initialised. If timers have already - been created then the initialisation will already have been performed. */ - prvCheckForValidListAndQueue(); - - if( xTimerQueue != NULL ) - { - #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 ) - { - /* Create the timer task, storing its handle in xTimerTaskHandle so - it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */ - xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle ); - } - #else - { - /* Create the timer task without storing its handle. */ - xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL); - } - #endif - } - - configASSERT( xReturn ); - return xReturn; -} -/*-----------------------------------------------------------*/ - -xTimerHandle ICACHE_FLASH_ATTR -xTimerCreate( const signed char * const pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) -{ -xTIMER *pxNewTimer; - - /* Allocate the timer structure. */ - if( xTimerPeriodInTicks == ( portTickType ) 0U ) - { - pxNewTimer = NULL; - configASSERT( ( xTimerPeriodInTicks > 0 ) ); - } - else - { - pxNewTimer = ( xTIMER * ) os_malloc( sizeof( xTIMER ) ); - if( pxNewTimer != NULL ) - { - /* Ensure the infrastructure used by the timer service task has been - created/initialised. */ - prvCheckForValidListAndQueue(); - - /* Initialise the timer structure members using the function parameters. */ - pxNewTimer->pcTimerName = pcTimerName; - pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; - pxNewTimer->uxAutoReload = uxAutoReload; - pxNewTimer->pvTimerID = pvTimerID; - pxNewTimer->pxCallbackFunction = pxCallbackFunction; - vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); - - traceTIMER_CREATE( pxNewTimer ); - } - else - { - traceTIMER_CREATE_FAILED(); - } - } - - return ( xTimerHandle ) pxNewTimer; -} -/*-----------------------------------------------------------*/ - -portBASE_TYPE ICACHE_FLASH_ATTR -xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) -{ -portBASE_TYPE xReturn = pdFAIL; -xTIMER_MESSAGE xMessage; - - /* Send a message to the timer service task to perform a particular action - on a particular timer definition. */ - if( xTimerQueue != NULL ) - { - /* Send a command to the timer service task to start the xTimer timer. */ - xMessage.xMessageID = xCommandID; - xMessage.xMessageValue = xOptionalValue; - xMessage.pxTimer = ( xTIMER * ) xTimer; - - if( pxHigherPriorityTaskWoken == NULL ) - { - if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) - { - xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime ); - } - else - { - xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); - } - } - else - { - xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); - } - - traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); - } - - return xReturn; -} -/*-----------------------------------------------------------*/ - -#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 ) - - xTaskHandle ICACHE_FLASH_ATTR - xTimerGetTimerDaemonTaskHandle( void ) - { - /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been - started, then xTimerTaskHandle will be NULL. */ - configASSERT( ( xTimerTaskHandle != NULL ) ); - return xTimerTaskHandle; - } - -#endif -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) -{ -xTIMER *pxTimer; -portBASE_TYPE xResult; - - /* Remove the timer from the list of active timers. A check has already - been performed to ensure the list is not empty. */ - pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); - ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); - traceTIMER_EXPIRED( pxTimer ); - - /* If the timer is an auto reload timer then calculate the next - expiry time and re-insert the timer in the list of active timers. */ - if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) - { - /* This is the only time a timer is inserted into a list using - a time relative to anything other than the current time. It - will therefore be inserted into the correct list relative to - the time this task thinks it is now, even if a command to - switch lists due to a tick count overflow is already waiting in - the timer queue. */ - if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE ) - { - /* The timer expired before it was added to the active timer - list. Reload it now. */ - xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY ); - configASSERT( xResult ); - ( void ) xResult; - } - } - - /* Call the timer callback. */ - pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); - //pxTimer->pxCallbackFunction( ( void * ) (pxTimer->pvTimerID) ); - -} -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvTimerTask( void *pvParameters ) -{ -portTickType xNextExpireTime; -portBASE_TYPE xListWasEmpty; - - /* Just to avoid compiler warnings. */ - ( void ) pvParameters; - - for( ;; ) - { - /* Query the timers list to see if it contains any timers, and if so, - obtain the time at which the next timer will expire. */ - xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); - - /* If a timer has expired, process it. Otherwise, block this task - until either a timer does expire, or a command is received. */ - prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); - - /* Empty the command queue. */ - prvProcessReceivedCommands(); - } -} -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) -{ -portTickType xTimeNow; -portBASE_TYPE xTimerListsWereSwitched; - - vTaskSuspendAll(); - { - /* Obtain the time now to make an assessment as to whether the timer - has expired or not. If obtaining the time causes the lists to switch - then don't process this timer as any timers that remained in the list - when the lists were switched will have been processed within the - prvSampelTimeNow() function. */ - xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); - if( xTimerListsWereSwitched == pdFALSE ) - { - /* The tick count has not overflowed, has the timer expired? */ - if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) - { - ( void ) xTaskResumeAll(); - prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); - } - else - { - /* The tick count has not overflowed, and the next expire - time has not been reached yet. This task should therefore - block to wait for the next expire time or a command to be - received - whichever comes first. The following line cannot - be reached unless xNextExpireTime > xTimeNow, except in the - case when the current timer list is empty. */ - vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) ); - - if( xTaskResumeAll() == pdFALSE ) - { - /* Yield to wait for either a command to arrive, or the block time - to expire. If a command arrived between the critical section being - exited and this yield then the yield will not cause the task - to block. */ - portYIELD_WITHIN_API(); - } - } - } - else - { - ( void ) xTaskResumeAll(); - } - } -} -/*-----------------------------------------------------------*/ - -static portTickType ICACHE_FLASH_ATTR -prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) -{ -portTickType xNextExpireTime; - - /* Timers are listed in expiry time order, with the head of the list - referencing the task that will expire first. Obtain the time at which - the timer with the nearest expiry time will expire. If there are no - active timers then just set the next expire time to 0. That will cause - this task to unblock when the tick count overflows, at which point the - timer lists will be switched and the next expiry time can be - re-assessed. */ - *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); - if( *pxListWasEmpty == pdFALSE ) - { - xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); - } - else - { - /* Ensure the task unblocks when the tick count rolls over. */ - xNextExpireTime = ( portTickType ) 0U; - } - - return xNextExpireTime; -} -/*-----------------------------------------------------------*/ - -static portTickType ICACHE_FLASH_ATTR -prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) -{ -portTickType xTimeNow; -PRIVILEGED_DATA static portTickType xLastTime = ( portTickType ) 0U; /*lint !e956 Variable is only accessible to one task. */ - - xTimeNow = xTaskGetTickCount(); - - if( xTimeNow < xLastTime ) - { - prvSwitchTimerLists( xLastTime ); - *pxTimerListsWereSwitched = pdTRUE; - } - else - { - *pxTimerListsWereSwitched = pdFALSE; - } - - xLastTime = xTimeNow; - - return xTimeNow; -} -/*-----------------------------------------------------------*/ - -static portBASE_TYPE ICACHE_FLASH_ATTR -prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) -{ -portBASE_TYPE xProcessTimerNow = pdFALSE; - - listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); - listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); - - if( xNextExpiryTime <= xTimeNow ) - { - /* Has the expiry time elapsed between the command to start/reset a - timer was issued, and the time the command was processed? */ - if( ( xTimeNow - xCommandTime ) >= pxTimer->xTimerPeriodInTicks ) - { - /* The time between a command being issued and the command being - processed actually exceeds the timers period. */ - xProcessTimerNow = pdTRUE; - } - else - { - vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); - } - } - else - { - if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) - { - /* If, since the command was issued, the tick count has overflowed - but the expiry time has not, then the timer must have already passed - its expiry time and should be processed immediately. */ - xProcessTimerNow = pdTRUE; - } - else - { - vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); - } - } - - return xProcessTimerNow; -} -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvProcessReceivedCommands( void ) -{ -xTIMER_MESSAGE xMessage; -xTIMER *pxTimer; -portBASE_TYPE xTimerListsWereSwitched, xResult; -portTickType xTimeNow; - - while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ - { - pxTimer = xMessage.pxTimer; - - if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) - { - /* The timer is in a list, remove it. */ - ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); - } - - traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue ); - - /* In this case the xTimerListsWereSwitched parameter is not used, but - it must be present in the function call. prvSampleTimeNow() must be - called after the message is received from xTimerQueue so there is no - possibility of a higher priority task adding a message to the message - queue with a time that is ahead of the timer daemon task (because it - pre-empted the timer daemon task after the xTimeNow value was set). */ - xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); - - switch( xMessage.xMessageID ) - { - case tmrCOMMAND_START : - /* Start or restart a timer. */ - if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE ) - { - /* The timer expired before it was added to the active timer - list. Process it now. */ - pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); - //pxTimer->pxCallbackFunction( ( void * ) (pxTimer->pvTimerID) ); - - if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) - { - xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); - configASSERT( xResult ); - ( void ) xResult; - } - } - break; - - case tmrCOMMAND_STOP : - /* The timer has already been removed from the active list. - There is nothing to do here. */ - break; - - case tmrCOMMAND_CHANGE_PERIOD : - pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue; - configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); - ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); - break; - - case tmrCOMMAND_DELETE : - /* The timer has already been removed from the active list, - just free up the memory. */ - os_free( pxTimer ); - break; - - default : - /* Don't expect to get here. */ - break; - } - } -} -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvSwitchTimerLists( portTickType xLastTime ) -{ -portTickType xNextExpireTime, xReloadTime; -xList *pxTemp; -xTIMER *pxTimer; -portBASE_TYPE xResult; - - /* Remove compiler warnings if configASSERT() is not defined. */ - ( void ) xLastTime; - - /* The tick count has overflowed. The timer lists must be switched. - If there are any timers still referenced from the current timer list - then they must have expired and should be processed before the lists - are switched. */ - while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) - { - xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); - - /* Remove the timer from the list. */ - pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); - ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); - - /* Execute its callback, then send a command to restart the timer if - it is an auto-reload timer. It cannot be restarted here as the lists - have not yet been switched. */ - pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); - //pxTimer->pxCallbackFunction( ( void * ) (pxTimer->pvTimerID) ); - - if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) - { - /* Calculate the reload value, and if the reload value results in - the timer going into the same timer list then it has already expired - and the timer should be re-inserted into the current list so it is - processed again within this loop. Otherwise a command should be sent - to restart the timer to ensure it is only inserted into a list after - the lists have been swapped. */ - xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); - if( xReloadTime > xNextExpireTime ) - { - listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); - listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); - vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); - } - else - { - xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY ); - configASSERT( xResult ); - ( void ) xResult; - } - } - } - - pxTemp = pxCurrentTimerList; - pxCurrentTimerList = pxOverflowTimerList; - pxOverflowTimerList = pxTemp; -} -/*-----------------------------------------------------------*/ - -static void ICACHE_FLASH_ATTR -prvCheckForValidListAndQueue( void ) -{ - /* Check that the list from which active timers are referenced, and the - queue used to communicate with the timer service, have been - initialised. */ - taskENTER_CRITICAL(); - { - if( xTimerQueue == NULL ) - { - vListInitialise( &xActiveTimerList1 ); - vListInitialise( &xActiveTimerList2 ); - pxCurrentTimerList = &xActiveTimerList1; - pxOverflowTimerList = &xActiveTimerList2; - xTimerQueue = xQueueCreate( ( unsigned portBASE_TYPE ) configTIMER_QUEUE_LENGTH, sizeof( xTIMER_MESSAGE ) ); - } - } - taskEXIT_CRITICAL(); -} -/*-----------------------------------------------------------*/ - -portBASE_TYPE ICACHE_FLASH_ATTR -xTimerIsTimerActive( xTimerHandle xTimer ) -{ -portBASE_TYPE xTimerIsInActiveList; -xTIMER *pxTimer = ( xTIMER * ) xTimer; - - /* Is the timer in the list of active timers? */ - taskENTER_CRITICAL(); - { - /* Checking to see if it is in the NULL list in effect checks to see if - it is referenced from either the current or the overflow timer lists in - one go, but the logic has to be reversed, hence the '!'. */ - xTimerIsInActiveList = !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); - } - taskEXIT_CRITICAL(); - - return xTimerIsInActiveList; -} -/*-----------------------------------------------------------*/ - -void * ICACHE_FLASH_ATTR -pvTimerGetTimerID( xTimerHandle xTimer ) -{ -xTIMER *pxTimer = ( xTIMER * ) xTimer; - - return pxTimer->pvTimerID; -} -/*-----------------------------------------------------------*/ - -/* This entire source file will be skipped if the application is not configured -to include software timer functionality. If you want to include software timer -functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ - -#endif /* configUSE_TIMERS == 1 */ +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS 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. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/timers.h" + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. This #if is closed at the very bottom +of this file. If you want to include software timer functionality then ensure +configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#if ( configUSE_TIMERS == 1 ) + +#ifdef MEMLEAK_DEBUG +static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; +#endif + +/* Misc definitions. */ +#define tmrNO_DELAY ( portTickType ) 0U + +/* The definition of the timers themselves. */ +typedef struct tmrTimerControl +{ + const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ + xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ + portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ + unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */ + void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ + tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */ +} xTIMER; + +/* The definition of messages that can be sent and received on the timer +queue. */ +typedef struct tmrTimerQueueMessage +{ + portBASE_TYPE xMessageID; /*<< The command being sent to the timer service task. */ + portTickType xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ + xTIMER * pxTimer; /*<< The timer to which the command will be applied. */ +} xTIMER_MESSAGE; + +/*lint -e956 A manual analysis and inspection has been used to determine which +static variables must be declared volatile. */ + +/* The list in which active timers are stored. Timers are referenced in expire +time order, with the nearest expiry time at the front of the list. Only the +timer service task is allowed to access xActiveTimerList. */ +PRIVILEGED_DATA static xList xActiveTimerList1; +PRIVILEGED_DATA static xList xActiveTimerList2; +PRIVILEGED_DATA static xList *pxCurrentTimerList; +PRIVILEGED_DATA static xList *pxOverflowTimerList; + +/* A queue that is used to send commands to the timer service task. */ +PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL; + +#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 ) + + PRIVILEGED_DATA static xTaskHandle xTimerTaskHandle = NULL; + +#endif + +/*lint +e956 */ + +/*-----------------------------------------------------------*/ + +/* + * Initialise the infrastructure used by the timer service task if it has not + * been initialised already. + */ +static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; + +/* + * The timer service task (daemon). Timer functionality is controlled by this + * task. Other tasks communicate with the timer service task using the + * xTimerQueue queue. + */ +static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION; + +/* + * Called by the timer service task to interpret and process a command it + * received on the timer queue. + */ +static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; + +/* + * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, + * depending on if the expire time causes a timer counter overflow. + */ +static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION; + +/* + * An active timer has reached its expire time. Reload the timer if it is an + * auto reload timer, then call its callback. + */ +static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION; + +/* + * The tick count has overflowed. Switch the timer lists after ensuring the + * current timer list does not still reference some timers. + */ +static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION; + +/* + * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE + * if a tick count overflow occurred since prvSampleTimeNow() was last called. + */ +static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; + +/* + * If the timer list contains any active timers then return the expire time of + * the timer that will expire first and set *pxListWasEmpty to false. If the + * timer list does not contain any timers then return 0 and set *pxListWasEmpty + * to pdTRUE. + */ +static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * If a timer has expired, process it. Otherwise, block the timer service task + * until either a timer does expire or a command is received. + */ +static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +portBASE_TYPE ICACHE_FLASH_ATTR +xTimerCreateTimerTask( void ) +{ +portBASE_TYPE xReturn = pdFAIL; + + /* This function is called when the scheduler is started if + configUSE_TIMERS is set to 1. Check that the infrastructure used by the + timer service task has been created/initialised. If timers have already + been created then the initialisation will already have been performed. */ + prvCheckForValidListAndQueue(); + + if( xTimerQueue != NULL ) + { + #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 ) + { + /* Create the timer task, storing its handle in xTimerTaskHandle so + it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */ + xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle ); + } + #else + { + /* Create the timer task without storing its handle. */ + xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL); + } + #endif + } + + configASSERT( xReturn ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +xTimerHandle ICACHE_FLASH_ATTR +xTimerCreate( const signed char * const pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) +{ +xTIMER *pxNewTimer; + + /* Allocate the timer structure. */ + if( xTimerPeriodInTicks == ( portTickType ) 0U ) + { + pxNewTimer = NULL; + configASSERT( ( xTimerPeriodInTicks > 0 ) ); + } + else + { + pxNewTimer = ( xTIMER * ) os_malloc( sizeof( xTIMER ) ); + if( pxNewTimer != NULL ) + { + /* Ensure the infrastructure used by the timer service task has been + created/initialised. */ + prvCheckForValidListAndQueue(); + + /* Initialise the timer structure members using the function parameters. */ + pxNewTimer->pcTimerName = pcTimerName; + pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; + pxNewTimer->uxAutoReload = uxAutoReload; + pxNewTimer->pvTimerID = pvTimerID; + pxNewTimer->pxCallbackFunction = pxCallbackFunction; + vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + + traceTIMER_CREATE( pxNewTimer ); + } + else + { + traceTIMER_CREATE_FAILED(); + } + } + + return ( xTimerHandle ) pxNewTimer; +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE ICACHE_FLASH_ATTR +xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) +{ +portBASE_TYPE xReturn = pdFAIL; +xTIMER_MESSAGE xMessage; + + /* Send a message to the timer service task to perform a particular action + on a particular timer definition. */ + if( xTimerQueue != NULL ) + { + /* Send a command to the timer service task to start the xTimer timer. */ + xMessage.xMessageID = xCommandID; + xMessage.xMessageValue = xOptionalValue; + xMessage.pxTimer = ( xTIMER * ) xTimer; + + if( pxHigherPriorityTaskWoken == NULL ) + { + if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime ); + } + else + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); + } + } + else + { + xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + } + + traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 ) + + xTaskHandle ICACHE_FLASH_ATTR + xTimerGetTimerDaemonTaskHandle( void ) + { + /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been + started, then xTimerTaskHandle will be NULL. */ + configASSERT( ( xTimerTaskHandle != NULL ) ); + return xTimerTaskHandle; + } + +#endif +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) +{ +xTIMER *pxTimer; +portBASE_TYPE xResult; + + /* Remove the timer from the list of active timers. A check has already + been performed to ensure the list is not empty. */ + pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* If the timer is an auto reload timer then calculate the next + expiry time and re-insert the timer in the list of active timers. */ + if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) + { + /* This is the only time a timer is inserted into a list using + a time relative to anything other than the current time. It + will therefore be inserted into the correct list relative to + the time this task thinks it is now, even if a command to + switch lists due to a tick count overflow is already waiting in + the timer queue. */ + if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE ) + { + /* The timer expired before it was added to the active timer + list. Reload it now. */ + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + + /* Call the timer callback. */ + pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); + //pxTimer->pxCallbackFunction( ( void * ) (pxTimer->pvTimerID) ); + +} +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvTimerTask( void *pvParameters ) +{ +portTickType xNextExpireTime; +portBASE_TYPE xListWasEmpty; + + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Query the timers list to see if it contains any timers, and if so, + obtain the time at which the next timer will expire. */ + xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); + + /* If a timer has expired, process it. Otherwise, block this task + until either a timer does expire, or a command is received. */ + prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); + + /* Empty the command queue. */ + prvProcessReceivedCommands(); + } +} +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) +{ +portTickType xTimeNow; +portBASE_TYPE xTimerListsWereSwitched; + + vTaskSuspendAll(); + { + /* Obtain the time now to make an assessment as to whether the timer + has expired or not. If obtaining the time causes the lists to switch + then don't process this timer as any timers that remained in the list + when the lists were switched will have been processed within the + prvSampelTimeNow() function. */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + if( xTimerListsWereSwitched == pdFALSE ) + { + /* The tick count has not overflowed, has the timer expired? */ + if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) + { + ( void ) xTaskResumeAll(); + prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); + } + else + { + /* The tick count has not overflowed, and the next expire + time has not been reached yet. This task should therefore + block to wait for the next expire time or a command to be + received - whichever comes first. The following line cannot + be reached unless xNextExpireTime > xTimeNow, except in the + case when the current timer list is empty. */ + vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) ); + + if( xTaskResumeAll() == pdFALSE ) + { + /* Yield to wait for either a command to arrive, or the block time + to expire. If a command arrived between the critical section being + exited and this yield then the yield will not cause the task + to block. */ + portYIELD_WITHIN_API(); + } + } + } + else + { + ( void ) xTaskResumeAll(); + } + } +} +/*-----------------------------------------------------------*/ + +static portTickType ICACHE_FLASH_ATTR +prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) +{ +portTickType xNextExpireTime; + + /* Timers are listed in expiry time order, with the head of the list + referencing the task that will expire first. Obtain the time at which + the timer with the nearest expiry time will expire. If there are no + active timers then just set the next expire time to 0. That will cause + this task to unblock when the tick count overflows, at which point the + timer lists will be switched and the next expiry time can be + re-assessed. */ + *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); + if( *pxListWasEmpty == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + } + else + { + /* Ensure the task unblocks when the tick count rolls over. */ + xNextExpireTime = ( portTickType ) 0U; + } + + return xNextExpireTime; +} +/*-----------------------------------------------------------*/ + +static portTickType ICACHE_FLASH_ATTR +prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) +{ +portTickType xTimeNow; +PRIVILEGED_DATA static portTickType xLastTime = ( portTickType ) 0U; /*lint !e956 Variable is only accessible to one task. */ + + xTimeNow = xTaskGetTickCount(); + + if( xTimeNow < xLastTime ) + { + prvSwitchTimerLists( xLastTime ); + *pxTimerListsWereSwitched = pdTRUE; + } + else + { + *pxTimerListsWereSwitched = pdFALSE; + } + + xLastTime = xTimeNow; + + return xTimeNow; +} +/*-----------------------------------------------------------*/ + +static portBASE_TYPE ICACHE_FLASH_ATTR +prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) +{ +portBASE_TYPE xProcessTimerNow = pdFALSE; + + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + + if( xNextExpiryTime <= xTimeNow ) + { + /* Has the expiry time elapsed between the command to start/reset a + timer was issued, and the time the command was processed? */ + if( ( xTimeNow - xCommandTime ) >= pxTimer->xTimerPeriodInTicks ) + { + /* The time between a command being issued and the command being + processed actually exceeds the timers period. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); + } + } + else + { + if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) + { + /* If, since the command was issued, the tick count has overflowed + but the expiry time has not, then the timer must have already passed + its expiry time and should be processed immediately. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + } + + return xProcessTimerNow; +} +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvProcessReceivedCommands( void ) +{ +xTIMER_MESSAGE xMessage; +xTIMER *pxTimer; +portBASE_TYPE xTimerListsWereSwitched, xResult; +portTickType xTimeNow; + + while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ + { + pxTimer = xMessage.pxTimer; + + if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) + { + /* The timer is in a list, remove it. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + } + + traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue ); + + /* In this case the xTimerListsWereSwitched parameter is not used, but + it must be present in the function call. prvSampleTimeNow() must be + called after the message is received from xTimerQueue so there is no + possibility of a higher priority task adding a message to the message + queue with a time that is ahead of the timer daemon task (because it + pre-empted the timer daemon task after the xTimeNow value was set). */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + + switch( xMessage.xMessageID ) + { + case tmrCOMMAND_START : + /* Start or restart a timer. */ + if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE ) + { + /* The timer expired before it was added to the active timer + list. Process it now. */ + pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); + //pxTimer->pxCallbackFunction( ( void * ) (pxTimer->pvTimerID) ); + + if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + break; + + case tmrCOMMAND_STOP : + /* The timer has already been removed from the active list. + There is nothing to do here. */ + break; + + case tmrCOMMAND_CHANGE_PERIOD : + pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue; + configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); + ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); + break; + + case tmrCOMMAND_DELETE : + /* The timer has already been removed from the active list, + just free up the memory. */ + os_free( pxTimer ); + break; + + default : + /* Don't expect to get here. */ + break; + } + } +} +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvSwitchTimerLists( portTickType xLastTime ) +{ +portTickType xNextExpireTime, xReloadTime; +xList *pxTemp; +xTIMER *pxTimer; +portBASE_TYPE xResult; + + /* Remove compiler warnings if configASSERT() is not defined. */ + ( void ) xLastTime; + + /* The tick count has overflowed. The timer lists must be switched. + If there are any timers still referenced from the current timer list + then they must have expired and should be processed before the lists + are switched. */ + while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + + /* Remove the timer from the list. */ + pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + + /* Execute its callback, then send a command to restart the timer if + it is an auto-reload timer. It cannot be restarted here as the lists + have not yet been switched. */ + pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer ); + //pxTimer->pxCallbackFunction( ( void * ) (pxTimer->pvTimerID) ); + + if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE ) + { + /* Calculate the reload value, and if the reload value results in + the timer going into the same timer list then it has already expired + and the timer should be re-inserted into the current list so it is + processed again within this loop. Otherwise a command should be sent + to restart the timer to ensure it is only inserted into a list after + the lists have been swapped. */ + xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); + if( xReloadTime > xNextExpireTime ) + { + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + else + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + } + + pxTemp = pxCurrentTimerList; + pxCurrentTimerList = pxOverflowTimerList; + pxOverflowTimerList = pxTemp; +} +/*-----------------------------------------------------------*/ + +static void ICACHE_FLASH_ATTR +prvCheckForValidListAndQueue( void ) +{ + /* Check that the list from which active timers are referenced, and the + queue used to communicate with the timer service, have been + initialised. */ + taskENTER_CRITICAL(); + { + if( xTimerQueue == NULL ) + { + vListInitialise( &xActiveTimerList1 ); + vListInitialise( &xActiveTimerList2 ); + pxCurrentTimerList = &xActiveTimerList1; + pxOverflowTimerList = &xActiveTimerList2; + xTimerQueue = xQueueCreate( ( unsigned portBASE_TYPE ) configTIMER_QUEUE_LENGTH, sizeof( xTIMER_MESSAGE ) ); + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE ICACHE_FLASH_ATTR +xTimerIsTimerActive( xTimerHandle xTimer ) +{ +portBASE_TYPE xTimerIsInActiveList; +xTIMER *pxTimer = ( xTIMER * ) xTimer; + + /* Is the timer in the list of active timers? */ + taskENTER_CRITICAL(); + { + /* Checking to see if it is in the NULL list in effect checks to see if + it is referenced from either the current or the overflow timer lists in + one go, but the logic has to be reversed, hence the '!'. */ + xTimerIsInActiveList = !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); + } + taskEXIT_CRITICAL(); + + return xTimerIsInActiveList; +} +/*-----------------------------------------------------------*/ + +void * ICACHE_FLASH_ATTR +pvTimerGetTimerID( xTimerHandle xTimer ) +{ +xTIMER *pxTimer = ( xTIMER * ) xTimer; + + return pxTimer->pvTimerID; +} +/*-----------------------------------------------------------*/ + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. If you want to include software timer +functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ + +#endif /* configUSE_TIMERS == 1 */ diff --git a/third_party/json/Makefile b/third_party/json/Makefile index 5cad8a37..37a0d892 100644 --- a/third_party/json/Makefile +++ b/third_party/json/Makefile @@ -1,46 +1,46 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -GEN_LIBS = libjson.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = libjson.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/third_party/lwip/apps/Makefile b/third_party/lwip/apps/Makefile old mode 100755 new mode 100644 index ba6cacad..3e9a602f --- a/third_party/lwip/apps/Makefile +++ b/third_party/lwip/apps/Makefile @@ -1,46 +1,46 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -GEN_LIBS = liblwipapps.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = liblwipapps.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/third_party/lwip/core/dhcp.c b/third_party/lwip/core/dhcp.c old mode 100755 new mode 100644 diff --git a/third_party/lwip/netif/ethernetif.c b/third_party/lwip/netif/ethernetif.c old mode 100755 new mode 100644 diff --git a/third_party/openssl/Makefile b/third_party/openssl/Makefile index 354bbb4a..3afa8fd1 100644 --- a/third_party/openssl/Makefile +++ b/third_party/openssl/Makefile @@ -1,54 +1,54 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR -UP_EXTRACT_DIR = .. -GEN_LIBS = libopenssl.a -COMPONENTS_libopenssl = library/liblibrary.a platform/libplatform.a -endif - -CCFLAGS += -fno-aggressive-loop-optimizations - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -DEFINES += -D_POSIX_SOURCE \ - -DLWIP_OPEN_SRC \ - -DPBUF_RSV_FOR_WLAN \ - -DEBUF_LWIP \ - -DMEMLEAK_DEBUG - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(SDK_PATH)/include/openssl/ \ - -I $(SDK_PATH)/include/openssl/openssl \ - -I $(SDK_PATH)/include/openssl/internal \ - -I $(SDK_PATH)/include/openssl/platform -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +UP_EXTRACT_DIR = .. +GEN_LIBS = libopenssl.a +COMPONENTS_libopenssl = library/liblibrary.a platform/libplatform.a +endif + +CCFLAGS += -fno-aggressive-loop-optimizations + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +DEFINES += -D_POSIX_SOURCE \ + -DLWIP_OPEN_SRC \ + -DPBUF_RSV_FOR_WLAN \ + -DEBUF_LWIP \ + -DMEMLEAK_DEBUG + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(SDK_PATH)/include/openssl/ \ + -I $(SDK_PATH)/include/openssl/openssl \ + -I $(SDK_PATH)/include/openssl/internal \ + -I $(SDK_PATH)/include/openssl/platform +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/third_party/openssl/library/Makefile b/third_party/openssl/library/Makefile index 836e81dc..10f4067c 100644 --- a/third_party/openssl/library/Makefile +++ b/third_party/openssl/library/Makefile @@ -1,46 +1,46 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -GEN_LIBS = liblibrary.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = liblibrary.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/third_party/openssl/library/ssl_cert.c b/third_party/openssl/library/ssl_cert.c old mode 100755 new mode 100644 diff --git a/third_party/openssl/library/ssl_lib.c b/third_party/openssl/library/ssl_lib.c old mode 100755 new mode 100644 diff --git a/third_party/openssl/library/ssl_pkey.c b/third_party/openssl/library/ssl_pkey.c old mode 100755 new mode 100644 diff --git a/third_party/openssl/library/ssl_x509.c b/third_party/openssl/library/ssl_x509.c old mode 100755 new mode 100644 diff --git a/third_party/openssl/platform/Makefile b/third_party/openssl/platform/Makefile index 3fc3ed23..749b4787 100644 --- a/third_party/openssl/platform/Makefile +++ b/third_party/openssl/platform/Makefile @@ -1,46 +1,46 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -GEN_LIBS = libplatform.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = libplatform.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/third_party/spiffs/Makefile b/third_party/spiffs/Makefile index 9fe92012..ad8d7a28 100644 --- a/third_party/spiffs/Makefile +++ b/third_party/spiffs/Makefile @@ -1,44 +1,44 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR -GEN_LIBS = libspiffs.a -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +GEN_LIBS = libspiffs.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/third_party/spiffs/esp_spiffs.c b/third_party/spiffs/esp_spiffs.c index 7778522a..8155dceb 100644 --- a/third_party/spiffs/esp_spiffs.c +++ b/third_party/spiffs/esp_spiffs.c @@ -1,292 +1,292 @@ -#include "esp_common.h" - -#include -#include - -#define NUM_SYS_FD 3 - -static spiffs fs; - -static u8_t *spiffs_work_buf; -static u8_t *spiffs_fd_buf; -static u8_t *spiffs_cache_buf; - -#define FLASH_UNIT_SIZE 4 - -static s32_t esp_spiffs_readwrite(u32_t addr, u32_t size, u8_t *p, int write) -{ - /* - * With proper configurarion spiffs never reads or writes more than - * LOG_PAGE_SIZE - */ - - if (size > fs.cfg.log_page_size) { - printf("Invalid size provided to read/write (%d)\n\r", (int) size); - return SPIFFS_ERR_NOT_CONFIGURED; - } - - char tmp_buf[fs.cfg.log_page_size + FLASH_UNIT_SIZE * 2]; - u32_t aligned_addr = addr & (-FLASH_UNIT_SIZE); - u32_t aligned_size = - ((size + (FLASH_UNIT_SIZE - 1)) & -FLASH_UNIT_SIZE) + FLASH_UNIT_SIZE; - - int res = spi_flash_read(aligned_addr, (u32_t *) tmp_buf, aligned_size); - - if (res != 0) { - printf("spi_flash_read failed: %d (%d, %d)\n\r", res, (int) aligned_addr, - (int) aligned_size); - return res; - } - - if (!write) { - memcpy(p, tmp_buf + (addr - aligned_addr), size); - return SPIFFS_OK; - } - - memcpy(tmp_buf + (addr - aligned_addr), p, size); - - res = spi_flash_write(aligned_addr, (u32_t *) tmp_buf, aligned_size); - - if (res != 0) { -// printf("spi_flash_write failed: %d (%d, %d)\n\r", res, -// (int) aligned_addr, (int) aligned_size); - return res; - } - - return SPIFFS_OK; -} - -static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst) -{ - return esp_spiffs_readwrite(addr, size, dst, 0); -} - -static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src) -{ - return esp_spiffs_readwrite(addr, size, src, 1); -} - -static s32_t esp_spiffs_erase(u32_t addr, u32_t size) -{ - /* - * With proper configurarion spiffs always - * provides here sector address & sector size - */ - if (size != fs.cfg.phys_erase_block || addr % fs.cfg.phys_erase_block != 0) { - printf("Invalid size provided to esp_spiffs_erase (%d, %d)\n\r", - (int) addr, (int) size); - return SPIFFS_ERR_NOT_CONFIGURED; - } - - return spi_flash_erase_sector(addr / fs.cfg.phys_erase_block); -} - -s32_t esp_spiffs_init(struct esp_spiffs_config *config) -{ - if (SPIFFS_mounted(&fs)) { - return -1; - } - - spiffs_config cfg; - s32_t ret; - - cfg.phys_size = config->phys_size; - cfg.phys_addr = config->phys_addr; - cfg.phys_erase_block = config->phys_erase_block; - cfg.log_block_size = config->log_block_size; - cfg.log_page_size = config->log_page_size; - - cfg.hal_read_f = esp_spiffs_read; - cfg.hal_write_f = esp_spiffs_write; - cfg.hal_erase_f = esp_spiffs_erase; - - if (spiffs_work_buf != NULL) { - free(spiffs_work_buf); - spiffs_work_buf = NULL; - } - spiffs_work_buf = malloc(config->log_page_size * 2); - - if (spiffs_work_buf == NULL) { - return -1; - } - - if (spiffs_fd_buf != NULL) { - free(spiffs_fd_buf); - spiffs_fd_buf = NULL; - } - spiffs_fd_buf = malloc(config->fd_buf_size); - - if (spiffs_fd_buf == NULL) { - free(spiffs_work_buf); - return -1; - } - - if (spiffs_cache_buf != NULL) { - free(spiffs_cache_buf); - spiffs_cache_buf = NULL; - } - spiffs_cache_buf = malloc(config->cache_buf_size); - - if (spiffs_cache_buf == NULL) { - free(spiffs_work_buf); - free(spiffs_fd_buf); - return -1; - } - - ret = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, - spiffs_fd_buf, config->fd_buf_size, - spiffs_cache_buf, config->cache_buf_size, - 0); - - if (ret == -1) { - free(spiffs_work_buf); - free(spiffs_fd_buf); - free(spiffs_cache_buf); - } - - return ret; -} - -void esp_spiffs_deinit(u8_t format) -{ - if (SPIFFS_mounted(&fs)) { - SPIFFS_unmount(&fs); - free(spiffs_work_buf); - free(spiffs_fd_buf); - free(spiffs_cache_buf); - - if (format) { - SPIFFS_format(&fs); - } - } -} - -int _open_r(struct _reent *r, const char *filename, int flags, int mode) -{ - spiffs_mode sm = 0; - int res; - int rw = (flags & 3); - - if (rw == O_RDONLY || rw == O_RDWR) { - sm |= SPIFFS_RDONLY; - } - - if (rw == O_WRONLY || rw == O_RDWR) { - sm |= SPIFFS_WRONLY; - } - - if (flags & O_CREAT) { - sm |= SPIFFS_CREAT; - } - - if (flags & O_TRUNC) { - sm |= SPIFFS_TRUNC; - } - - if (flags & O_APPEND) { - sm |= SPIFFS_APPEND; - } - - /* Supported in newer versions of SPIFFS. */ - /* if (flags && O_EXCL) sm |= SPIFFS_EXCL; */ - /* if (flags && O_DIRECT) sm |= SPIFFS_DIRECT; */ - - res = SPIFFS_open(&fs, (char *) filename, sm, 0); - - if (res >= 0) { - res += NUM_SYS_FD; - } - - return res; -} - -_ssize_t _read_r(struct _reent *r, int fd, void *buf, size_t len) -{ - - ssize_t res; - - if (fd < NUM_SYS_FD) { - res = -1; - } else { - res = SPIFFS_read(&fs, fd - NUM_SYS_FD, buf, len); - } - - return res; -} - -_ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len) -{ - - if (fd < NUM_SYS_FD) { - return -1; - } - - int res = SPIFFS_write(&fs, fd - NUM_SYS_FD, (char *) buf, len); - return res; -} - -_off_t _lseek_r(struct _reent *r, int fd, _off_t where, int whence) -{ - - ssize_t res; - - if (fd < NUM_SYS_FD) { - res = -1; - } else { - res = SPIFFS_lseek(&fs, fd - NUM_SYS_FD, where, whence); - } - - return res; -} - -int _close_r(struct _reent *r, int fd) -{ - - if (fd < NUM_SYS_FD) { - return -1; - } - - SPIFFS_close(&fs, fd - NUM_SYS_FD); - return 0; -} - -int _rename_r(struct _reent *r, const char *from, const char *to) -{ - - int res = SPIFFS_rename(&fs, (char *) from, (char *) to); - return res; -} - -int _unlink_r(struct _reent *r, const char *filename) -{ - - int res = SPIFFS_remove(&fs, (char *) filename); - return res; -} - -int _fstat_r(struct _reent *r, int fd, struct stat *s) -{ - - int res; - spiffs_stat ss; - memset(s, 0, sizeof(*s)); - - if (fd < NUM_SYS_FD) { - s->st_ino = fd; - s->st_rdev = fd; - s->st_mode = S_IFCHR | 0666; - return 0; - } - - res = SPIFFS_fstat(&fs, fd - NUM_SYS_FD, &ss); - - if (res < 0) { - return res; - } - - s->st_ino = ss.obj_id; - s->st_mode = 0666; - s->st_nlink = 1; - s->st_size = ss.size; - return 0; -} +#include "esp_common.h" + +#include +#include + +#define NUM_SYS_FD 3 + +static spiffs fs; + +static u8_t *spiffs_work_buf; +static u8_t *spiffs_fd_buf; +static u8_t *spiffs_cache_buf; + +#define FLASH_UNIT_SIZE 4 + +static s32_t esp_spiffs_readwrite(u32_t addr, u32_t size, u8_t *p, int write) +{ + /* + * With proper configurarion spiffs never reads or writes more than + * LOG_PAGE_SIZE + */ + + if (size > fs.cfg.log_page_size) { + printf("Invalid size provided to read/write (%d)\n\r", (int) size); + return SPIFFS_ERR_NOT_CONFIGURED; + } + + char tmp_buf[fs.cfg.log_page_size + FLASH_UNIT_SIZE * 2]; + u32_t aligned_addr = addr & (-FLASH_UNIT_SIZE); + u32_t aligned_size = + ((size + (FLASH_UNIT_SIZE - 1)) & -FLASH_UNIT_SIZE) + FLASH_UNIT_SIZE; + + int res = spi_flash_read(aligned_addr, (u32_t *) tmp_buf, aligned_size); + + if (res != 0) { + printf("spi_flash_read failed: %d (%d, %d)\n\r", res, (int) aligned_addr, + (int) aligned_size); + return res; + } + + if (!write) { + memcpy(p, tmp_buf + (addr - aligned_addr), size); + return SPIFFS_OK; + } + + memcpy(tmp_buf + (addr - aligned_addr), p, size); + + res = spi_flash_write(aligned_addr, (u32_t *) tmp_buf, aligned_size); + + if (res != 0) { +// printf("spi_flash_write failed: %d (%d, %d)\n\r", res, +// (int) aligned_addr, (int) aligned_size); + return res; + } + + return SPIFFS_OK; +} + +static s32_t esp_spiffs_read(u32_t addr, u32_t size, u8_t *dst) +{ + return esp_spiffs_readwrite(addr, size, dst, 0); +} + +static s32_t esp_spiffs_write(u32_t addr, u32_t size, u8_t *src) +{ + return esp_spiffs_readwrite(addr, size, src, 1); +} + +static s32_t esp_spiffs_erase(u32_t addr, u32_t size) +{ + /* + * With proper configurarion spiffs always + * provides here sector address & sector size + */ + if (size != fs.cfg.phys_erase_block || addr % fs.cfg.phys_erase_block != 0) { + printf("Invalid size provided to esp_spiffs_erase (%d, %d)\n\r", + (int) addr, (int) size); + return SPIFFS_ERR_NOT_CONFIGURED; + } + + return spi_flash_erase_sector(addr / fs.cfg.phys_erase_block); +} + +s32_t esp_spiffs_init(struct esp_spiffs_config *config) +{ + if (SPIFFS_mounted(&fs)) { + return -1; + } + + spiffs_config cfg; + s32_t ret; + + cfg.phys_size = config->phys_size; + cfg.phys_addr = config->phys_addr; + cfg.phys_erase_block = config->phys_erase_block; + cfg.log_block_size = config->log_block_size; + cfg.log_page_size = config->log_page_size; + + cfg.hal_read_f = esp_spiffs_read; + cfg.hal_write_f = esp_spiffs_write; + cfg.hal_erase_f = esp_spiffs_erase; + + if (spiffs_work_buf != NULL) { + free(spiffs_work_buf); + spiffs_work_buf = NULL; + } + spiffs_work_buf = malloc(config->log_page_size * 2); + + if (spiffs_work_buf == NULL) { + return -1; + } + + if (spiffs_fd_buf != NULL) { + free(spiffs_fd_buf); + spiffs_fd_buf = NULL; + } + spiffs_fd_buf = malloc(config->fd_buf_size); + + if (spiffs_fd_buf == NULL) { + free(spiffs_work_buf); + return -1; + } + + if (spiffs_cache_buf != NULL) { + free(spiffs_cache_buf); + spiffs_cache_buf = NULL; + } + spiffs_cache_buf = malloc(config->cache_buf_size); + + if (spiffs_cache_buf == NULL) { + free(spiffs_work_buf); + free(spiffs_fd_buf); + return -1; + } + + ret = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, + spiffs_fd_buf, config->fd_buf_size, + spiffs_cache_buf, config->cache_buf_size, + 0); + + if (ret == -1) { + free(spiffs_work_buf); + free(spiffs_fd_buf); + free(spiffs_cache_buf); + } + + return ret; +} + +void esp_spiffs_deinit(u8_t format) +{ + if (SPIFFS_mounted(&fs)) { + SPIFFS_unmount(&fs); + free(spiffs_work_buf); + free(spiffs_fd_buf); + free(spiffs_cache_buf); + + if (format) { + SPIFFS_format(&fs); + } + } +} + +int _open_r(struct _reent *r, const char *filename, int flags, int mode) +{ + spiffs_mode sm = 0; + int res; + int rw = (flags & 3); + + if (rw == O_RDONLY || rw == O_RDWR) { + sm |= SPIFFS_RDONLY; + } + + if (rw == O_WRONLY || rw == O_RDWR) { + sm |= SPIFFS_WRONLY; + } + + if (flags & O_CREAT) { + sm |= SPIFFS_CREAT; + } + + if (flags & O_TRUNC) { + sm |= SPIFFS_TRUNC; + } + + if (flags & O_APPEND) { + sm |= SPIFFS_APPEND; + } + + /* Supported in newer versions of SPIFFS. */ + /* if (flags && O_EXCL) sm |= SPIFFS_EXCL; */ + /* if (flags && O_DIRECT) sm |= SPIFFS_DIRECT; */ + + res = SPIFFS_open(&fs, (char *) filename, sm, 0); + + if (res >= 0) { + res += NUM_SYS_FD; + } + + return res; +} + +_ssize_t _read_r(struct _reent *r, int fd, void *buf, size_t len) +{ + + ssize_t res; + + if (fd < NUM_SYS_FD) { + res = -1; + } else { + res = SPIFFS_read(&fs, fd - NUM_SYS_FD, buf, len); + } + + return res; +} + +_ssize_t _write_r(struct _reent *r, int fd, void *buf, size_t len) +{ + + if (fd < NUM_SYS_FD) { + return -1; + } + + int res = SPIFFS_write(&fs, fd - NUM_SYS_FD, (char *) buf, len); + return res; +} + +_off_t _lseek_r(struct _reent *r, int fd, _off_t where, int whence) +{ + + ssize_t res; + + if (fd < NUM_SYS_FD) { + res = -1; + } else { + res = SPIFFS_lseek(&fs, fd - NUM_SYS_FD, where, whence); + } + + return res; +} + +int _close_r(struct _reent *r, int fd) +{ + + if (fd < NUM_SYS_FD) { + return -1; + } + + SPIFFS_close(&fs, fd - NUM_SYS_FD); + return 0; +} + +int _rename_r(struct _reent *r, const char *from, const char *to) +{ + + int res = SPIFFS_rename(&fs, (char *) from, (char *) to); + return res; +} + +int _unlink_r(struct _reent *r, const char *filename) +{ + + int res = SPIFFS_remove(&fs, (char *) filename); + return res; +} + +int _fstat_r(struct _reent *r, int fd, struct stat *s) +{ + + int res; + spiffs_stat ss; + memset(s, 0, sizeof(*s)); + + if (fd < NUM_SYS_FD) { + s->st_ino = fd; + s->st_rdev = fd; + s->st_mode = S_IFCHR | 0666; + return 0; + } + + res = SPIFFS_fstat(&fs, fd - NUM_SYS_FD, &ss); + + if (res < 0) { + return res; + } + + s->st_ino = ss.obj_id; + s->st_mode = 0666; + s->st_nlink = 1; + s->st_size = ss.size; + return 0; +} diff --git a/third_party/ssl/Makefile b/third_party/ssl/Makefile index 0aff9d14..b476376b 100644 --- a/third_party/ssl/Makefile +++ b/third_party/ssl/Makefile @@ -1,47 +1,47 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR -UP_EXTRACT_DIR = .. -GEN_LIBS = libssl.a -COMPONENTS_libssl = crypto/libsslcrypto.a \ - ssl/libsslssl.a -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR +UP_EXTRACT_DIR = .. +GEN_LIBS = libssl.a +COMPONENTS_libssl = crypto/libsslcrypto.a \ + ssl/libsslssl.a +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/third_party/ssl/crypto/Makefile b/third_party/ssl/crypto/Makefile index d26b65a9..c59000f9 100644 --- a/third_party/ssl/crypto/Makefile +++ b/third_party/ssl/crypto/Makefile @@ -1,46 +1,46 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -GEN_LIBS = libsslcrypto.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = libsslcrypto.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/third_party/ssl/ssl/Makefile b/third_party/ssl/ssl/Makefile index 7ab2721a..6433ee25 100644 --- a/third_party/ssl/ssl/Makefile +++ b/third_party/ssl/ssl/Makefile @@ -1,46 +1,46 @@ - -############################################################# -# Required variables for each makefile -# Discard this section from all parent makefiles -# Expected variables (with automatic defaults): -# CSRCS (all "C" files in the dir) -# SUBDIRS (all subdirs with a Makefile) -# GEN_LIBS - list of libs to be generated () -# GEN_IMAGES - list of images to be generated () -# COMPONENTS_xxx - a list of libs/objs in the form -# subdir/lib to be extracted and rolled up into -# a generated lib/image xxx.a () -# -ifndef PDIR - -GEN_LIBS = libsslssl.a - -endif - - -############################################################# -# Configuration i.e. compile options etc. -# Target specific stuff (defines etc.) goes in here! -# Generally values applying to a tree are captured in the -# makefile at its root level - these are then overridden -# for a subtree within the makefile rooted therein -# -#DEFINES += - -############################################################# -# Recursion Magic - Don't touch this!! -# -# Each subtree potentially has an include directory -# corresponding to the common APIs applicable to modules -# rooted at that subtree. Accordingly, the INCLUDE PATH -# of a module can only contain the include directories up -# its parent path, and not its siblings -# -# Required for each makefile to inherit from the parent -# - -INCLUDES := $(INCLUDES) -I $(PDIR)include -INCLUDES += -I ./ -PDIR := ../$(PDIR) -sinclude $(PDIR)Makefile - + +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of images to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# +ifndef PDIR + +GEN_LIBS = libsslssl.a + +endif + + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# +#DEFINES += + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I $(PDIR)include +INCLUDES += -I ./ +PDIR := ../$(PDIR) +sinclude $(PDIR)Makefile + diff --git a/tools/make_cacert.py b/tools/make_cacert.py old mode 100755 new mode 100644 diff --git a/tools/make_cert.py b/tools/make_cert.py old mode 100755 new mode 100644 diff --git a/tools/makefile.sh b/tools/makefile.sh old mode 100644 new mode 100755