mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-07 14:44:32 +02:00
Merge branch 'master' into driver_merge_tmp/merge_uart
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- test_report
|
||||
- deploy
|
||||
|
||||
before_script:
|
||||
@@ -92,6 +93,20 @@ build_examples:
|
||||
- cd build_examples
|
||||
- ${IDF_PATH}/make/build_examples.sh
|
||||
|
||||
build_docs:
|
||||
stage: build
|
||||
image: espressif/esp32-ci-env
|
||||
tags:
|
||||
- build_docs
|
||||
script:
|
||||
- cd docs
|
||||
- make html
|
||||
artifacts:
|
||||
paths:
|
||||
- docs/_build/html
|
||||
expire_in: 1 mos
|
||||
|
||||
|
||||
test_nvs_on_host:
|
||||
stage: test
|
||||
image: espressif/esp32-ci-env
|
||||
@@ -112,13 +127,12 @@ test_build_system:
|
||||
- ./make/test_build_system.sh
|
||||
|
||||
test_report:
|
||||
stage: deploy
|
||||
stage: test_report
|
||||
only:
|
||||
- master
|
||||
- triggers
|
||||
tags:
|
||||
- test_report
|
||||
allow_failure: true
|
||||
variables:
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test"
|
||||
@@ -127,7 +141,7 @@ test_report:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORT_PATH
|
||||
expire_in: 6 mos
|
||||
expire_in: 12 mos
|
||||
script:
|
||||
# clone test bench
|
||||
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
|
||||
@@ -159,6 +173,31 @@ push_master_to_github:
|
||||
- git push --follow-tags github HEAD:master
|
||||
|
||||
|
||||
deploy_docs:
|
||||
before_script:
|
||||
- echo "Not setting up GitLab key, not fetching submodules"
|
||||
stage: deploy
|
||||
only:
|
||||
- master
|
||||
- triggers
|
||||
tags:
|
||||
- deploy
|
||||
image: espressif/esp32-ci-env
|
||||
script:
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- echo -n $DOCS_DEPLOY_KEY > ~/.ssh/id_rsa_base64
|
||||
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host $DOCS_SERVER\n\tStrictHostKeyChecking no\n\tUser $DOCS_SERVER_USER\n" >> ~/.ssh/config
|
||||
- export GIT_VER=$(git describe --always)
|
||||
- cd docs/_build/
|
||||
- mv html $GIT_VER
|
||||
- tar czvf $GIT_VER.tar.gz $GIT_VER
|
||||
- scp $GIT_VER.tar.gz $DOCS_SERVER:$DOCS_PATH
|
||||
- ssh $DOCS_SERVER -x "cd $DOCS_PATH && tar xzvf $GIT_VER.tar.gz && rm -f latest && ln -s $GIT_VER latest"
|
||||
|
||||
|
||||
# AUTO GENERATED PART START, DO NOT MODIFY CONTENT BELOW
|
||||
# template for test jobs
|
||||
.test_template: &test_template
|
||||
|
@@ -1,12 +1,15 @@
|
||||
# Contributions Guide
|
||||
Contributions Guide
|
||||
===================
|
||||
|
||||
We welcome contributions to the esp-idf project!
|
||||
|
||||
## How to Contribute
|
||||
How to Contribute
|
||||
-----------------
|
||||
|
||||
Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via [Github Pull Requests](https://help.github.com/articles/about-pull-requests/).
|
||||
Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via `Github Pull Requests <https://help.github.com/articles/about-pull-requests/>`_.
|
||||
|
||||
## Before Contributing
|
||||
Before Contributing
|
||||
-------------------
|
||||
|
||||
Before sending us a Pull Request, please consider this list of points:
|
||||
|
||||
@@ -16,15 +19,16 @@ Before sending us a Pull Request, please consider this list of points:
|
||||
|
||||
* Is the code adequately commented for people to understand how it is structured?
|
||||
|
||||
* Is there documentation or examples that go with code contributions? [There are additional suggestions for writing good examples in the examples README](examples/README.md).
|
||||
* Is there documentation or examples that go with code contributions? `There are additional suggestions for writing good examples in the examples README <https://github.com/espressif/esp-idf/tree/master/examples>`_.
|
||||
|
||||
* Are comments and documentation written in clear English, with no spelling or grammar errors?
|
||||
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" [squashed into previous commits](http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/)?
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits <http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/>`_?
|
||||
|
||||
* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
|
||||
|
||||
## Pull Request Process
|
||||
Pull Request Process
|
||||
--------------------
|
||||
|
||||
After you open the Pull Request, there will probably be some discussion in the comments field of the request itself.
|
||||
|
||||
@@ -32,6 +36,9 @@ Once the Pull Request is ready to merge, it will first be merged into our intern
|
||||
|
||||
If this process passes, it will be merged onto the public github repository.
|
||||
|
||||
## Legal Part
|
||||
Legal Part
|
||||
----------
|
||||
|
||||
Before a contribution can be accepted, you will need to sign our `Contributor Agreement <http://esp-idf.readthedocs.io/en/latest/contributing.html>`_. You will be prompted for this automatically as part of the Pull Request process.
|
||||
|
||||
|
||||
Before a contribution can be accepted, you will need to sign our [Contributor Agreement](docs/contributor-agreement.rst). You will be prompted for this automatically as part of the Pull Request process.
|
@@ -1,5 +1,7 @@
|
||||
# Using Espressif IoT Development Framework with the ESP32
|
||||
|
||||
[](http://esp-idf.readthedocs.io/en/latest/?badge=latest)
|
||||
|
||||
# Setting Up ESP-IDF
|
||||
|
||||
In the [docs](docs) directory you will find per-platform setup guides:
|
||||
@@ -60,14 +62,15 @@ The simplest way to use the partition table is to `make menuconfig` and choose o
|
||||
|
||||
In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
|
||||
|
||||
For more details about partition tables and how to create custom variations, view the `docs/partition_tables.rst` file.
|
||||
For more details about partition tables and how to create custom variations, view the `docs/partition-tables.rst` file.
|
||||
|
||||
# Resources
|
||||
|
||||
* The [docs directory of the esp-idf repository](docs) contains esp-idf documentation.
|
||||
* The [docs directory of the esp-idf repository](docs) contains source of [esp-idf](http://esp-idf.readthedocs.io/) documentation.
|
||||
|
||||
* The [esp32.com forum](http://esp32.com/) is a place to ask questions and find community resources.
|
||||
|
||||
* [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one.
|
||||
|
||||
* If you're interested in contributing to esp-idf, please check the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
||||
* If you're interested in contributing to esp-idf, please check the [Contributions Guide](http://esp-idf.readthedocs.io/en/latest/contributing.html>).
|
||||
|
||||
|
@@ -28,37 +28,36 @@ extern "C" {
|
||||
*
|
||||
* This function should be called only once, before any other BT functions are called.
|
||||
*/
|
||||
void bt_controller_init();
|
||||
void bt_controller_init(void);
|
||||
|
||||
/** @brief: vhci_host_callback
|
||||
/** @brief vhci_host_callback
|
||||
* used for vhci call host function to notify what host need to do
|
||||
*
|
||||
* notify_host_send_available: notify host can send packet to controller
|
||||
* notify_host_recv: notify host that controller has packet send to host
|
||||
*/
|
||||
typedef struct vhci_host_callback {
|
||||
|
||||
void (*notify_host_send_available)(void);
|
||||
int (*notify_host_recv)(uint8_t *data, uint16_t len);
|
||||
} vhci_host_callback_t;
|
||||
|
||||
/** @brief: API_vhci_host_check_send_available
|
||||
/** @brief API_vhci_host_check_send_available
|
||||
* used for check actively if the host can send packet to controller or not.
|
||||
* return true for ready to send, false means cannot send packet
|
||||
* @return true for ready to send, false means cannot send packet
|
||||
*/
|
||||
bool API_vhci_host_check_send_available(void);
|
||||
|
||||
/** @brief: API_vhci_host_send_packet
|
||||
/** @brief API_vhci_host_send_packet
|
||||
* host send packet to controller
|
||||
* param data is the packet point, the param len is the packet length
|
||||
* return void
|
||||
* @param data the packet point
|
||||
*,@param len the packet length
|
||||
*/
|
||||
void API_vhci_host_send_packet(uint8_t *data, uint16_t len);
|
||||
|
||||
/** @brief: API_vhci_host_register_callback
|
||||
/** @brief API_vhci_host_register_callback
|
||||
* register the vhci referece callback, the call back
|
||||
* struct defined by vhci_host_callback structure.
|
||||
* param is the vhci_host_callback type variable
|
||||
* @param callback vhci_host_callback type variable
|
||||
*/
|
||||
void API_vhci_host_register_callback(const vhci_host_callback_t *callback);
|
||||
|
||||
|
@@ -27,46 +27,44 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char* GPIO_TAG;
|
||||
#define GPIO_SEL_0 (BIT(0)) /*!< Pin 0 selected */
|
||||
#define GPIO_SEL_1 (BIT(1)) /*!< Pin 1 selected */
|
||||
#define GPIO_SEL_2 (BIT(2)) /*!< Pin 2 selected */
|
||||
#define GPIO_SEL_3 (BIT(3)) /*!< Pin 3 selected */
|
||||
#define GPIO_SEL_4 (BIT(4)) /*!< Pin 4 selected */
|
||||
#define GPIO_SEL_5 (BIT(5)) /*!< Pin 5 selected */
|
||||
#define GPIO_SEL_6 (BIT(6)) /*!< Pin 6 selected */
|
||||
#define GPIO_SEL_7 (BIT(7)) /*!< Pin 7 selected */
|
||||
#define GPIO_SEL_8 (BIT(8)) /*!< Pin 8 selected */
|
||||
#define GPIO_SEL_9 (BIT(9)) /*!< Pin 9 selected */
|
||||
#define GPIO_SEL_10 (BIT(10)) /*!< Pin 10 selected */
|
||||
#define GPIO_SEL_11 (BIT(11)) /*!< Pin 11 selected */
|
||||
#define GPIO_SEL_12 (BIT(12)) /*!< Pin 12 selected */
|
||||
#define GPIO_SEL_13 (BIT(13)) /*!< Pin 13 selected */
|
||||
#define GPIO_SEL_14 (BIT(14)) /*!< Pin 14 selected */
|
||||
#define GPIO_SEL_15 (BIT(15)) /*!< Pin 15 selected */
|
||||
#define GPIO_SEL_16 (BIT(16)) /*!< Pin 16 selected */
|
||||
#define GPIO_SEL_17 (BIT(17)) /*!< Pin 17 selected */
|
||||
#define GPIO_SEL_18 (BIT(18)) /*!< Pin 18 selected */
|
||||
#define GPIO_SEL_19 (BIT(19)) /*!< Pin 19 selected */
|
||||
|
||||
#define GPIO_SEL_0 (BIT(0)) /* Pin 0 selected */
|
||||
#define GPIO_SEL_1 (BIT(1)) /* Pin 1 selected */
|
||||
#define GPIO_SEL_2 (BIT(2)) /* Pin 2 selected */
|
||||
#define GPIO_SEL_3 (BIT(3)) /* Pin 3 selected */
|
||||
#define GPIO_SEL_4 (BIT(4)) /* Pin 4 selected */
|
||||
#define GPIO_SEL_5 (BIT(5)) /* Pin 5 selected */
|
||||
#define GPIO_SEL_6 (BIT(6)) /* Pin 6 selected */
|
||||
#define GPIO_SEL_7 (BIT(7)) /* Pin 7 selected */
|
||||
#define GPIO_SEL_8 (BIT(8)) /* Pin 8 selected */
|
||||
#define GPIO_SEL_9 (BIT(9)) /* Pin 9 selected */
|
||||
#define GPIO_SEL_10 (BIT(10)) /* Pin 10 selected */
|
||||
#define GPIO_SEL_11 (BIT(11)) /* Pin 11 selected */
|
||||
#define GPIO_SEL_12 (BIT(12)) /* Pin 12 selected */
|
||||
#define GPIO_SEL_13 (BIT(13)) /* Pin 13 selected */
|
||||
#define GPIO_SEL_14 (BIT(14)) /* Pin 14 selected */
|
||||
#define GPIO_SEL_15 (BIT(15)) /* Pin 15 selected */
|
||||
#define GPIO_SEL_16 (BIT(16)) /* Pin 16 selected */
|
||||
#define GPIO_SEL_17 (BIT(17)) /* Pin 17 selected */
|
||||
#define GPIO_SEL_18 (BIT(18)) /* Pin 18 selected */
|
||||
#define GPIO_SEL_19 (BIT(19)) /* Pin 19 selected */
|
||||
#define GPIO_SEL_21 (BIT(21)) /*!< Pin 21 selected */
|
||||
#define GPIO_SEL_22 (BIT(22)) /*!< Pin 22 selected */
|
||||
#define GPIO_SEL_23 (BIT(23)) /*!< Pin 23 selected */
|
||||
|
||||
#define GPIO_SEL_21 (BIT(21)) /* Pin 21 selected */
|
||||
#define GPIO_SEL_22 (BIT(22)) /* Pin 22 selected */
|
||||
#define GPIO_SEL_23 (BIT(23)) /* Pin 23 selected */
|
||||
#define GPIO_SEL_25 (BIT(25)) /*!< Pin 25 selected */
|
||||
#define GPIO_SEL_26 (BIT(26)) /*!< Pin 26 selected */
|
||||
#define GPIO_SEL_27 (BIT(27)) /*!< Pin 27 selected */
|
||||
|
||||
#define GPIO_SEL_25 (BIT(25)) /* Pin 25 selected */
|
||||
#define GPIO_SEL_26 (BIT(26)) /* Pin 26 selected */
|
||||
#define GPIO_SEL_27 (BIT(27)) /* Pin 27 selected */
|
||||
|
||||
#define GPIO_SEL_32 ((uint64_t)(((uint64_t)1)<<32)) /* Pin 32 selected */
|
||||
#define GPIO_SEL_33 ((uint64_t)(((uint64_t)1)<<33)) /* Pin 33 selected */
|
||||
#define GPIO_SEL_34 ((uint64_t)(((uint64_t)1)<<34)) /* Pin 34 selected */
|
||||
#define GPIO_SEL_35 ((uint64_t)(((uint64_t)1)<<35)) /* Pin 35 selected */
|
||||
#define GPIO_SEL_36 ((uint64_t)(((uint64_t)1)<<36)) /* Pin 36 selected */
|
||||
#define GPIO_SEL_37 ((uint64_t)(((uint64_t)1)<<37)) /* Pin 37 selected */
|
||||
#define GPIO_SEL_38 ((uint64_t)(((uint64_t)1)<<38)) /* Pin 38 selected */
|
||||
#define GPIO_SEL_39 ((uint64_t)(((uint64_t)1)<<39)) /* Pin 39 selected */
|
||||
#define GPIO_SEL_32 ((uint64_t)(((uint64_t)1)<<32)) /*!< Pin 32 selected */
|
||||
#define GPIO_SEL_33 ((uint64_t)(((uint64_t)1)<<33)) /*!< Pin 33 selected */
|
||||
#define GPIO_SEL_34 ((uint64_t)(((uint64_t)1)<<34)) /*!< Pin 34 selected */
|
||||
#define GPIO_SEL_35 ((uint64_t)(((uint64_t)1)<<35)) /*!< Pin 35 selected */
|
||||
#define GPIO_SEL_36 ((uint64_t)(((uint64_t)1)<<36)) /*!< Pin 36 selected */
|
||||
#define GPIO_SEL_37 ((uint64_t)(((uint64_t)1)<<37)) /*!< Pin 37 selected */
|
||||
#define GPIO_SEL_38 ((uint64_t)(((uint64_t)1)<<38)) /*!< Pin 38 selected */
|
||||
#define GPIO_SEL_39 ((uint64_t)(((uint64_t)1)<<39)) /*!< Pin 39 selected */
|
||||
|
||||
#define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U
|
||||
#define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U
|
||||
@@ -120,127 +118,100 @@ extern const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT];
|
||||
#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 34)) //to decide whether it can be a valid GPIO number of output mode
|
||||
|
||||
typedef enum {
|
||||
GPIO_NUM_0 = 0,
|
||||
GPIO_NUM_1 = 1,
|
||||
GPIO_NUM_2 = 2,
|
||||
GPIO_NUM_3 = 3,
|
||||
GPIO_NUM_4 = 4,
|
||||
GPIO_NUM_5 = 5,
|
||||
GPIO_NUM_6 = 6,
|
||||
GPIO_NUM_7 = 7,
|
||||
GPIO_NUM_8 = 8,
|
||||
GPIO_NUM_9 = 9,
|
||||
GPIO_NUM_10 = 10,
|
||||
GPIO_NUM_11 = 11,
|
||||
GPIO_NUM_12 = 12,
|
||||
GPIO_NUM_13 = 13,
|
||||
GPIO_NUM_14 = 14,
|
||||
GPIO_NUM_15 = 15,
|
||||
GPIO_NUM_16 = 16,
|
||||
GPIO_NUM_17 = 17,
|
||||
GPIO_NUM_18 = 18,
|
||||
GPIO_NUM_19 = 19,
|
||||
GPIO_NUM_0 = 0, /*!< GPIO0, input and output */
|
||||
GPIO_NUM_1 = 1, /*!< GPIO1, input and output */
|
||||
GPIO_NUM_2 = 2, /*!< GPIO2, input and output */
|
||||
GPIO_NUM_3 = 3, /*!< GPIO3, input and output */
|
||||
GPIO_NUM_4 = 4, /*!< GPIO4, input and output */
|
||||
GPIO_NUM_5 = 5, /*!< GPIO5, input and output */
|
||||
GPIO_NUM_6 = 6, /*!< GPIO6, input and output */
|
||||
GPIO_NUM_7 = 7, /*!< GPIO7, input and output */
|
||||
GPIO_NUM_8 = 8, /*!< GPIO8, input and output */
|
||||
GPIO_NUM_9 = 9, /*!< GPIO9, input and output */
|
||||
GPIO_NUM_10 = 10, /*!< GPIO10, input and output */
|
||||
GPIO_NUM_11 = 11, /*!< GPIO11, input and output */
|
||||
GPIO_NUM_12 = 12, /*!< GPIO12, input and output */
|
||||
GPIO_NUM_13 = 13, /*!< GPIO13, input and output */
|
||||
GPIO_NUM_14 = 14, /*!< GPIO14, input and output */
|
||||
GPIO_NUM_15 = 15, /*!< GPIO15, input and output */
|
||||
GPIO_NUM_16 = 16, /*!< GPIO16, input and output */
|
||||
GPIO_NUM_17 = 17, /*!< GPIO17, input and output */
|
||||
GPIO_NUM_18 = 18, /*!< GPIO18, input and output */
|
||||
GPIO_NUM_19 = 19, /*!< GPIO19, input and output */
|
||||
|
||||
GPIO_NUM_21 = 21,
|
||||
GPIO_NUM_22 = 22,
|
||||
GPIO_NUM_23 = 23,
|
||||
GPIO_NUM_21 = 21, /*!< GPIO21, input and output */
|
||||
GPIO_NUM_22 = 22, /*!< GPIO22, input and output */
|
||||
GPIO_NUM_23 = 23, /*!< GPIO23, input and output */
|
||||
|
||||
GPIO_NUM_25 = 25,
|
||||
GPIO_NUM_26 = 26,
|
||||
GPIO_NUM_27 = 27,
|
||||
GPIO_NUM_25 = 25, /*!< GPIO25, input and output */
|
||||
GPIO_NUM_26 = 26, /*!< GPIO26, input and output */
|
||||
GPIO_NUM_27 = 27, /*!< GPIO27, input and output */
|
||||
|
||||
GPIO_NUM_32 = 32,
|
||||
GPIO_NUM_33 = 33,
|
||||
GPIO_NUM_34 = 34, /*input mode only */
|
||||
GPIO_NUM_35 = 35, /*input mode only */
|
||||
GPIO_NUM_36 = 36, /*input mode only */
|
||||
GPIO_NUM_37 = 37, /*input mode only */
|
||||
GPIO_NUM_38 = 38, /*input mode only */
|
||||
GPIO_NUM_39 = 39, /*input mode only */
|
||||
GPIO_NUM_32 = 32, /*!< GPIO32, input and output */
|
||||
GPIO_NUM_33 = 33, /*!< GPIO32, input and output */
|
||||
GPIO_NUM_34 = 34, /*!< GPIO34, input mode only */
|
||||
GPIO_NUM_35 = 35, /*!< GPIO35, input mode only */
|
||||
GPIO_NUM_36 = 36, /*!< GPIO36, input mode only */
|
||||
GPIO_NUM_37 = 37, /*!< GPIO37, input mode only */
|
||||
GPIO_NUM_38 = 38, /*!< GPIO38, input mode only */
|
||||
GPIO_NUM_39 = 39, /*!< GPIO39, input mode only */
|
||||
} gpio_num_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_INTR_DISABLE = 0, /* disable GPIO interrupt */
|
||||
GPIO_INTR_POSEDGE = 1, /* GPIO interrupt type : rising edge */
|
||||
GPIO_INTR_NEGEDGE = 2, /* GPIO interrupt type : falling edge */
|
||||
GPIO_INTR_ANYEDGE = 3, /* GPIO interrupt type : both rising and falling edge */
|
||||
GPIO_INTR_LOW_LEVEL = 4, /* GPIO interrupt type : input low level trigger */
|
||||
GPIO_INTR_HIGH_LEVEL = 5, /* GPIO interrupt type : input high level trigger */
|
||||
GPIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */
|
||||
GPIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */
|
||||
GPIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */
|
||||
GPIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */
|
||||
GPIO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : input low level trigger */
|
||||
GPIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */
|
||||
GPIO_INTR_MAX,
|
||||
} gpio_int_type_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT, /* GPIO mode : input only */
|
||||
GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT, /* GPIO mode : output only mode */
|
||||
GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /* GPIO mode : output only with open-drain mode */
|
||||
GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /* GPIO mode : output and input with open-drain mode*/
|
||||
GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)), /* GPIO mode : output and input mode */
|
||||
GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT, /*!< GPIO mode : input only */
|
||||
GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT, /*!< GPIO mode : output only mode */
|
||||
GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /*!< GPIO mode : output only with open-drain mode */
|
||||
GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /*!< GPIO mode : output and input with open-drain mode*/
|
||||
GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)), /*!< GPIO mode : output and input mode */
|
||||
} gpio_mode_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_PULLUP_DISABLE = 0x0, /* disable GPIO pull-up resistor */
|
||||
GPIO_PULLUP_ENABLE = 0x1, /* enable GPIO pull-up resistor */
|
||||
GPIO_PULLUP_DISABLE = 0x0, /*!< Disable GPIO pull-up resistor */
|
||||
GPIO_PULLUP_ENABLE = 0x1, /*!< Enable GPIO pull-up resistor */
|
||||
} gpio_pullup_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_PULLDOWN_DISABLE = 0x0, /* disable GPIO pull-down resistor */
|
||||
GPIO_PULLDOWN_ENABLE = 0x1, /* enable GPIO pull-down resistor */
|
||||
GPIO_PULLDOWN_DISABLE = 0x0, /*!< Disable GPIO pull-down resistor */
|
||||
GPIO_PULLDOWN_ENABLE = 0x1, /*!< Enable GPIO pull-down resistor */
|
||||
} gpio_pulldown_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t pin_bit_mask; /* GPIO pin: set with bit mask, each bit maps to a GPIO */
|
||||
gpio_mode_t mode; /* GPIO mode: set input/output mode */
|
||||
gpio_pullup_t pull_up_en; /* GPIO pull-up */
|
||||
gpio_pulldown_t pull_down_en; /* GPIO pull-down */
|
||||
gpio_int_type_t intr_type; /* GPIO interrupt type */
|
||||
uint64_t pin_bit_mask; /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
|
||||
gpio_mode_t mode; /*!< GPIO mode: set input/output mode */
|
||||
gpio_pullup_t pull_up_en; /*!< GPIO pull-up */
|
||||
gpio_pulldown_t pull_down_en; /*!< GPIO pull-down */
|
||||
gpio_int_type_t intr_type; /*!< GPIO interrupt type */
|
||||
} gpio_config_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_LOW_LEVEL = 0,
|
||||
GPIO_HIGH_LEVEL = 1,
|
||||
GPIO_LEVEL_ERR,
|
||||
} gpio_level_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_PULLUP_ONLY, /* Pad pull up */
|
||||
GPIO_PULLDOWN_ONLY, /* Pad pull down */
|
||||
GPIO_PULLUP_PULLDOWN, /* Pad pull up + pull down*/
|
||||
GPIO_FLOATING, /* Pad floating */
|
||||
GPIO_PULLUP_ONLY, /*!< Pad pull up */
|
||||
GPIO_PULLDOWN_ONLY, /*!< Pad pull down */
|
||||
GPIO_PULLUP_PULLDOWN, /*!< Pad pull up + pull down*/
|
||||
GPIO_FLOATING, /*!< Pad floating */
|
||||
} gpio_pull_mode_t;
|
||||
|
||||
typedef void (*gpio_event_callback)(gpio_num_t gpio_intr_num);
|
||||
|
||||
/** \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 GPIO common configuration
|
||||
*
|
||||
* Use this Function ,Configure GPIO's Mode,pull-up,PullDown,IntrType
|
||||
* Configure GPIO's Mode,pull-up,PullDown,IntrType
|
||||
*
|
||||
* @parameter[in] pGPIOConfig
|
||||
* pGPIOConfig.pin_bit_mask : Configure GPIO pins bits,set this parameter with bit mask.
|
||||
* If you want to configure GPIO34 and GPIO16, pin_bit_mask=GPIO_Pin_16|GPIO_Pin_34;
|
||||
* pGPIOConfig.mode : Configure GPIO mode,such as output ,input...
|
||||
* pGPIOConfig.pull_up_en : Enable or Disable pull-up
|
||||
* pGPIOConfig.pull_down_en : Enable or Disable pull-down
|
||||
* pGPIOConfig.intr_type : Configure GPIO interrupt trigger type
|
||||
* @return ESP_OK: success ;
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_FAIL : GPIO error
|
||||
* @param pGPIOConfig Pointer to GPIO configure struct
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_config(gpio_config_t *pGPIOConfig);
|
||||
@@ -249,36 +220,36 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig);
|
||||
/**
|
||||
* @brief GPIO set interrupt trigger type
|
||||
*
|
||||
* @parameter[in] gpio_num : GPIO number.
|
||||
* If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @parameter[in] intr_type: interrupt type, select from gpio_int_type_t
|
||||
* @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param intr_type Interrupt type, select from gpio_int_type_t
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type);
|
||||
|
||||
/**
|
||||
* @brief enable GPIO module interrupt signal
|
||||
* @brief Enable GPIO module interrupt signal
|
||||
*
|
||||
* @parameter[in] gpio_num : GPIO number.
|
||||
* If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_intr_enable(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief disable GPIO module interrupt signal
|
||||
* @brief Disable GPIO module interrupt signal
|
||||
*
|
||||
* @parameter[in] gpio_num : GPIO number.
|
||||
* If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_intr_disable(gpio_num_t gpio_num);
|
||||
@@ -286,12 +257,12 @@ esp_err_t gpio_intr_disable(gpio_num_t gpio_num);
|
||||
/**
|
||||
* @brief GPIO set output level
|
||||
*
|
||||
* @parameter[in] gpio_num : GPIO number.
|
||||
* If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @parameter[in] level : Output level. 0: low ; 1: high
|
||||
* @param gpio_num GPIO number. If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param level Output level. 0: low ; 1: high
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_FAIL : GPIO error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - GPIO_IS_VALID_GPIO GPIO number error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);
|
||||
@@ -299,11 +270,11 @@ esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);
|
||||
/**
|
||||
* @brief GPIO get input level
|
||||
*
|
||||
* @parameter[in] gpio_num : GPIO number.
|
||||
* If you want to get level of pin GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param gpio_num GPIO number. If you want to get level of pin GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*
|
||||
* @return 0 : the GPIO input level is 0
|
||||
* 1 : the GPIO input level is 1
|
||||
* @return
|
||||
* - 0 the GPIO input level is 0
|
||||
* - 1 the GPIO input level is 1
|
||||
*
|
||||
*/
|
||||
int gpio_get_level(gpio_num_t gpio_num);
|
||||
@@ -313,13 +284,12 @@ int gpio_get_level(gpio_num_t gpio_num);
|
||||
*
|
||||
* Configure GPIO direction,such as output_only,input_only,output_and_input
|
||||
*
|
||||
* @parameter[in] gpio_num : Configure GPIO pins number,it should be GPIO number.
|
||||
* If you want to set direction of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @parameter[in] mode : Configure GPIO direction,such as output_only,input_only,...
|
||||
* @param gpio_num Configure GPIO pins number, it should be GPIO number. If you want to set direction of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param mode GPIO direction
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG : fail
|
||||
* ESP_FAIL : GPIO error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG GPIO error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
|
||||
@@ -329,13 +299,12 @@ esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
|
||||
*
|
||||
* User this Function,configure GPIO pull mode,such as pull-up,pull-down
|
||||
*
|
||||
* @parameter[in] gpio_num : Configure GPIO pins number,it should be GPIO number.
|
||||
* If you want to set pull up or down mode for GPIO16,gpio_num should be GPIO_NUM_16 (16);
|
||||
* @parameter[in] pull : Configure GPIO pull up/down mode,such as pullup_only,pulldown_only,pullup_and_pulldown,...
|
||||
* @param gpio_num GPIO number. If you want to set pull up or down mode for GPIO16,gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param pull GPIO pull up/down mode.
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG : fail
|
||||
* ESP_FAIL : GPIO error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG : Parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
|
||||
@@ -343,78 +312,99 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
|
||||
/**
|
||||
* @brief enable GPIO wake-up function.
|
||||
*
|
||||
* @param gpio_num_t gpio_num : GPIO number.
|
||||
* @param gpio_num GPIO number.
|
||||
*
|
||||
* @param gpio_int_type_t intr_type : only GPIO_INTR_LOLEVEL\GPIO_INTR_HILEVEL can be used
|
||||
* @param intr_type GPIO wake-up type. Only GPIO_INTR_LOLEVEL\GPIO_INTR_HILEVEL can be used
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);
|
||||
|
||||
/**
|
||||
* @brief disable GPIO wake-up function.
|
||||
* @brief Disable GPIO wake-up function.
|
||||
*
|
||||
* @param gpio_num_t gpio_num: GPIO number
|
||||
* @param gpio_num GPIO number
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief register GPIO interrupt handler, the handler is an ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @note
|
||||
* Users should know that which CPU is running and then pick a INUM that is not used by system.
|
||||
* We can find the information of INUM and interrupt level in soc.h.
|
||||
* TODO: to move INUM options to menu_config
|
||||
* @parameter uint32_t gpio_intr_num : GPIO interrupt number,check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @parameter void (* fn)(void* ) : interrupt handler function.
|
||||
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
|
||||
* @parameter void * arg : parameter for handler function
|
||||
*
|
||||
* @return ESP_OK : success ;
|
||||
* ESP_FAIL: gpio error
|
||||
* @param gpio_intr_num GPIO interrupt number,check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @param fn Interrupt handler function.
|
||||
*
|
||||
* @note
|
||||
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
|
||||
*
|
||||
* @param arg Parameter for handler function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success ;
|
||||
* - ESP_ERR_INVALID_ARG GPIO error
|
||||
*/
|
||||
esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg);
|
||||
|
||||
/**
|
||||
* *************** ATTENTION ********************/
|
||||
/**
|
||||
*
|
||||
*@attention
|
||||
* Each GPIO has its own separate configuration register, so we do not use
|
||||
* a lock to serialize access to them. This works under the assumption that
|
||||
* no situation will occur where two tasks try to configure the same GPIO
|
||||
* pin simultaneously. It is up to the application developer to guarantee this.
|
||||
*/
|
||||
|
||||
|
||||
/*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ */
|
||||
/* gpio_config_t io_conf;
|
||||
/**
|
||||
*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ *
|
||||
* @code{c}
|
||||
* gpio_config_t io_conf;
|
||||
* io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
|
||||
* io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode
|
||||
* io_conf.pin_bit_mask = GPIO_SEL_18 | GPIO_SEL_19; //bit mask of the pins that you want to set,e.g.GPIO18/19
|
||||
* io_conf.pull_down_en = 0; //disable pull-down mode
|
||||
* io_conf.pull_up_en = 0; //disable pull-up mode
|
||||
* gpio_config(&io_conf); //configure GPIO with the given settings
|
||||
* @endcode
|
||||
**/
|
||||
/*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ */
|
||||
/* io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt
|
||||
|
||||
/**
|
||||
*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ *
|
||||
* @code{c}
|
||||
* io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt
|
||||
* io_conf.mode = GPIO_MODE_INPUT; //set as input
|
||||
* io_conf.pin_bit_mask = GPIO_SEL_4 | GPIO_SEL_5; //bit mask of the pins that you want to set, e.g.,GPIO4/5
|
||||
* io_conf.pull_down_en = 0; //disable pull-down mode
|
||||
* io_conf.pull_up_en = 1; //enable pull-up mode
|
||||
* gpio_config(&io_conf); //configure GPIO with the given settings
|
||||
*----------EXAMPLE TO SET ISR HANDLER ----------------------*/
|
||||
/* gpio_isr_register(18,gpio_intr_test,NULL); //hook the isr handler for GPIO interrupt
|
||||
* @endcode
|
||||
*/
|
||||
/**
|
||||
*----------EXAMPLE TO SET ISR HANDLER ----------------------
|
||||
* @code{c}
|
||||
* //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
|
||||
* //NOTE1:user should arrange the INUMs that used, better not to use a same INUM for different interrupt.
|
||||
* //NOTE2:do not pick the INUM that already occupied by the system.
|
||||
* //NOTE3:refer to soc.h to check which INUMs that can be used.
|
||||
*-------------EXAMPLE OF HANDLER FUNCTION-------------------*/
|
||||
/*#include "esp_attr.h"
|
||||
* gpio_isr_register(18,gpio_intr_test,NULL); //hook the isr handler for GPIO interrupt
|
||||
* @endcode
|
||||
* @note
|
||||
* 1. user should arrange the INUMs that used, better not to use a same INUM for different interrupt.
|
||||
* 2. do not pick the INUM that already occupied by the system.
|
||||
* 3. refer to soc.h to check which INUMs that can be used.
|
||||
*/
|
||||
/**
|
||||
*-------------EXAMPLE OF HANDLER FUNCTION-------------------*
|
||||
* @code{c}
|
||||
* #include "esp_attr.h"
|
||||
* void IRAM_ATTR gpio_intr_test(void* arg)
|
||||
*{
|
||||
* {
|
||||
* //GPIO intr process
|
||||
* ets_printf("in gpio_intr\n");
|
||||
* uint32_t gpio_num = 0;
|
||||
@@ -435,9 +425,14 @@ esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * ar
|
||||
* }
|
||||
* }
|
||||
* } while(++gpio_num < GPIO_PIN_COUNT);
|
||||
*}
|
||||
*----EXAMPLE OF I2C CONFIG AND PICK SIGNAL FOR IO MATRIX---*/
|
||||
/* gpio_config_t io_conf;
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
/**
|
||||
*----EXAMPLE OF I2C CONFIG AND PICK SIGNAL FOR IO MATRIX---*
|
||||
* @code{c}
|
||||
* gpio_config_t io_conf;
|
||||
* io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
|
||||
* io_conf.mode = GPIO_MODE_INPUT_OUTPUT_OD; //set as output mode
|
||||
* io_conf.pin_bit_mask = GPIO_SEL_21 | GPIO_SEL_22; //bit mask of the pins that you want to set,e.g.GPIO21/22
|
||||
@@ -447,17 +442,10 @@ esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * ar
|
||||
* gpio_matrix_out(21, EXT_I2C_SCL_O_IDX, 0, 0); //set output signal for io_matrix
|
||||
* gpio_matrix_out(22, EXT_I2C_SDA_O_IDX, 0, 0); //set output signal for io_matrix
|
||||
* gpio_matrix_in( 22, EXT_I2C_SDA_I_IDX, 0); //set input signal for io_matrix
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -31,68 +31,68 @@ extern const char* LEDC_TAG;
|
||||
#define LEDC_REF_CLK_HZ (1*1000000)
|
||||
|
||||
typedef enum {
|
||||
LEDC_HIGH_SPEED_MODE = 0, /*LEDC high speed speed_mode */
|
||||
LEDC_HIGH_SPEED_MODE = 0, /*!< LEDC high speed speed_mode */
|
||||
//in this version, we only support high speed speed_mode. We will access low speed speed_mode later
|
||||
//LEDC_LOW_SPEED_MODE, /*LEDC low speed speed_mode */
|
||||
LEDC_SPEED_MODE_MAX,
|
||||
//LEDC_LOW_SPEED_MODE, /*!< LEDC low speed speed_mode */
|
||||
LEDC_SPEED_MODE_MAX, /*!< LEDC speed limit */
|
||||
} ledc_mode_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_INTR_DISABLE = 0, /*Disable LEDC interrupt */
|
||||
LEDC_INTR_FADE_END, /*Enable LEDC interrupt */
|
||||
LEDC_INTR_DISABLE = 0, /*!< Disable LEDC interrupt */
|
||||
LEDC_INTR_FADE_END, /*!< Enable LEDC interrupt */
|
||||
} ledc_intr_type_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_DUTY_DIR_DECREASE = 0, /*LEDC duty decrease direction */
|
||||
LEDC_DUTY_DIR_INCREASE = 1, /*LEDC duty increase direction */
|
||||
LEDC_DUTY_DIR_DECREASE = 0, /*!< LEDC duty decrease direction */
|
||||
LEDC_DUTY_DIR_INCREASE = 1, /*!< LEDC duty increase direction */
|
||||
} ledc_duty_direction_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_REF_TICK = 0, /*LEDC timer clock divided from reference tick(1Mhz) */
|
||||
LEDC_APB_CLK, /*LEDC timer clock divided from APB clock(80Mhz)*/
|
||||
LEDC_REF_TICK = 0, /*!< LEDC timer clock divided from reference tick(1Mhz) */
|
||||
LEDC_APB_CLK, /*!< LEDC timer clock divided from APB clock(80Mhz)*/
|
||||
} ledc_clk_src_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_TIMER_0 = 0, /*LEDC source timer TIMER0 */
|
||||
LEDC_TIMER_1, /*LEDC source timer TIMER1 */
|
||||
LEDC_TIMER_2, /*LEDC source timer TIMER2 */
|
||||
LEDC_TIMER_3, /*LEDC source timer TIMER3 */
|
||||
LEDC_TIMER_0 = 0, /*!< LEDC source timer TIMER0 */
|
||||
LEDC_TIMER_1, /*!< LEDC source timer TIMER1 */
|
||||
LEDC_TIMER_2, /*!< LEDC source timer TIMER2 */
|
||||
LEDC_TIMER_3, /*!< LEDC source timer TIMER3 */
|
||||
} ledc_timer_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_CHANNEL_0 = 0, /*LEDC channel 0 */
|
||||
LEDC_CHANNEL_1, /*LEDC channel 1 */
|
||||
LEDC_CHANNEL_2, /*LEDC channel 2 */
|
||||
LEDC_CHANNEL_3, /*LEDC channel 3 */
|
||||
LEDC_CHANNEL_4, /*LEDC channel 4 */
|
||||
LEDC_CHANNEL_5, /*LEDC channel 5 */
|
||||
LEDC_CHANNEL_6, /*LEDC channel 6 */
|
||||
LEDC_CHANNEL_7, /*LEDC channel 7 */
|
||||
LEDC_CHANNEL_0 = 0, /*!< LEDC channel 0 */
|
||||
LEDC_CHANNEL_1, /*!< LEDC channel 1 */
|
||||
LEDC_CHANNEL_2, /*!< LEDC channel 2 */
|
||||
LEDC_CHANNEL_3, /*!< LEDC channel 3 */
|
||||
LEDC_CHANNEL_4, /*!< LEDC channel 4 */
|
||||
LEDC_CHANNEL_5, /*!< LEDC channel 5 */
|
||||
LEDC_CHANNEL_6, /*!< LEDC channel 6 */
|
||||
LEDC_CHANNEL_7, /*!< LEDC channel 7 */
|
||||
} ledc_channel_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_TIMER_10_BIT = 10, /*LEDC PWM depth 10Bit */
|
||||
LEDC_TIMER_11_BIT = 11, /*LEDC PWM depth 11Bit */
|
||||
LEDC_TIMER_12_BIT = 12, /*LEDC PWM depth 12Bit */
|
||||
LEDC_TIMER_13_BIT = 13, /*LEDC PWM depth 13Bit */
|
||||
LEDC_TIMER_14_BIT = 14, /*LEDC PWM depth 14Bit */
|
||||
LEDC_TIMER_15_BIT = 15, /*LEDC PWM depth 15Bit */
|
||||
LEDC_TIMER_10_BIT = 10, /*!< LEDC PWM depth 10Bit */
|
||||
LEDC_TIMER_11_BIT = 11, /*!< LEDC PWM depth 11Bit */
|
||||
LEDC_TIMER_12_BIT = 12, /*!< LEDC PWM depth 12Bit */
|
||||
LEDC_TIMER_13_BIT = 13, /*!< LEDC PWM depth 13Bit */
|
||||
LEDC_TIMER_14_BIT = 14, /*!< LEDC PWM depth 14Bit */
|
||||
LEDC_TIMER_15_BIT = 15, /*!< LEDC PWM depth 15Bit */
|
||||
} ledc_timer_bit_t;
|
||||
|
||||
typedef struct {
|
||||
int gpio_num; /*the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16*/
|
||||
ledc_mode_t speed_mode; /*LEDC speed speed_mode, high-speed mode or low-speed mode*/
|
||||
ledc_channel_t channel; /*LEDC channel(0 - 7)*/
|
||||
ledc_intr_type_t intr_type; /*configure interrupt, Fade interrupt enable or Fade interrupt disable*/
|
||||
ledc_timer_t timer_sel; /*Select the timer source of channel (0 - 3)*/
|
||||
uint32_t duty; /*LEDC channel duty, the duty range is [0, (2**bit_num) - 1], */
|
||||
int gpio_num; /*!< the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16*/
|
||||
ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode*/
|
||||
ledc_channel_t channel; /*!< LEDC channel(0 - 7)*/
|
||||
ledc_intr_type_t intr_type; /*!< configure interrupt, Fade interrupt enable or Fade interrupt disable*/
|
||||
ledc_timer_t timer_sel; /*!< Select the timer source of channel (0 - 3)*/
|
||||
uint32_t duty; /*!< LEDC channel duty, the duty range is [0, (2**bit_num) - 1], */
|
||||
} ledc_channel_config_t;
|
||||
|
||||
typedef struct {
|
||||
ledc_mode_t speed_mode; /*LEDC speed speed_mode, high-speed mode or low-speed mode*/
|
||||
ledc_timer_bit_t bit_num; /*LEDC channel duty depth*/
|
||||
ledc_timer_t timer_num; /*The timer source of channel (0 - 3)*/
|
||||
uint32_t freq_hz; /*LEDC timer frequency(Hz)*/
|
||||
ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode*/
|
||||
ledc_timer_bit_t bit_num; /*!< LEDC channel duty depth*/
|
||||
ledc_timer_t timer_num; /*!< The timer source of channel (0 - 3)*/
|
||||
uint32_t freq_hz; /*!< LEDC timer frequency(Hz)*/
|
||||
} ledc_timer_config_t;
|
||||
|
||||
|
||||
@@ -101,15 +101,10 @@ typedef struct {
|
||||
*
|
||||
* User this Function, configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC depth
|
||||
*
|
||||
* @param[in] ledc_channel_config_t
|
||||
* ledc_channel_config_t.speed_mode : LEDC speed speed_mode
|
||||
* ledc_channel_config_t.gpio_num : LEDC output gpio_num, if you want to use gpio16, ledc_channel_config_t.gpio_num = 16
|
||||
* ledc_channel_config_t.channel : LEDC channel(0 - 7)
|
||||
* ledc_channel_config_t.intr_type : configure interrupt, Fade interrupt enable or Fade interrupt disable
|
||||
* ledc_channel_config_t.timer_sel : Select the timer source of channel (0 - 3), high speed channel must bind with high speed timer.
|
||||
* ledc_channel_config_t.duty : LEDC channel duty, the duty range is [0, (2**timer_bit_num) - 1],
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* @param ledc_conf Pointer of LEDC channel configure struct
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf);
|
||||
@@ -119,14 +114,13 @@ esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf);
|
||||
*
|
||||
* User this Function, configure LEDC timer with the given source timer/frequency(Hz)/bit_num
|
||||
*
|
||||
* @param[in] ledc_timer_config_t
|
||||
* ledc_timer_config_t.speed_mode : LEDC speed speed_mode
|
||||
* ledc_timer_config_t.timer_num : Select the timer source of channel (0 - 3)
|
||||
* ledc_timer_config_t.freq_hz : LEDC channel frequency(Hz),
|
||||
* ledc_timer_config_t.bit_num : LEDC channel duty depth
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_FAIL: Can not find a proper pre-divider number base on the given frequency and the current bit_num.
|
||||
* @param timer_conf Pointer of LEDC timer configure struct
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current bit_num.
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf);
|
||||
@@ -137,12 +131,13 @@ esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf);
|
||||
* Call this function to activate the LEDC updated parameters.
|
||||
* After ledc_set_duty, ledc_set_fade, we need to call this function to update the settings.
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
|
||||
* @param channel LEDC channel(0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
|
||||
@@ -152,12 +147,13 @@ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
|
||||
*
|
||||
* Disable LEDC output, and set idle level
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
|
||||
* @param channel LEDC channel(0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level);
|
||||
|
||||
@@ -166,27 +162,29 @@ esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idl
|
||||
*
|
||||
* Set LEDC frequency(Hz)
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_num : LEDC timer index(0-3), select from ledc_timer_t
|
||||
* @param timer_num LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
* @param[in] freq_hz : set the LEDC frequency
|
||||
* @param freq_hz Set the LEDC frequency
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_FAIL: Can not find a proper pre-divider number base on the given frequency and the current bit_num.
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current bit_num.
|
||||
*/
|
||||
esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz);
|
||||
|
||||
/**
|
||||
* @brief LEDC get channel frequency(Hz)
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_num : LEDC timer index(0-3), select from ledc_timer_t
|
||||
* @param timer_num LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return 0 : error
|
||||
* others : current LEDC frequency
|
||||
* @return
|
||||
* - 0 error
|
||||
* - Others Current LEDC frequency
|
||||
*
|
||||
*/
|
||||
uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num);
|
||||
@@ -196,27 +194,29 @@ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num);
|
||||
*
|
||||
* Set LEDC duty, After the function calls the ledc_update_duty function, the function can take effect.
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
|
||||
* @param channel LEDC channel(0-7), select from ledc_channel_t
|
||||
*
|
||||
* @param[in] duty : set the LEDC duty, the duty range is [0, (2**bit_num) - 1]
|
||||
* @param duty Set the LEDC duty, the duty range is [0, (2**bit_num) - 1]
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty);
|
||||
|
||||
/**
|
||||
* @brief LEDC get duty
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
|
||||
* @param channel LEDC channel(0-7), select from ledc_channel_t
|
||||
*
|
||||
*
|
||||
* @return -1: parameter error
|
||||
* other value: current LEDC duty
|
||||
* @return
|
||||
* - (-1) parameter error
|
||||
* - Others Current LEDC duty
|
||||
*
|
||||
*/
|
||||
int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
|
||||
@@ -226,22 +226,23 @@ int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
|
||||
*
|
||||
* Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect.
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
|
||||
* @param channel LEDC channel(0-7), select from ledc_channel_t
|
||||
*
|
||||
* @param[in] duty : set the start of the gradient duty, the duty range is [0, (2**bit_num) - 1]
|
||||
* @param duty Set the start of the gradient duty, the duty range is [0, (2**bit_num) - 1]
|
||||
*
|
||||
* @param[in] gradule_direction : set the direction of the gradient
|
||||
* @param gradule_direction Set the direction of the gradient
|
||||
*
|
||||
* @param[in] step_num : set the number of the gradient
|
||||
* @param step_num Set the number of the gradient
|
||||
*
|
||||
* @param[in] duty_cyle_num : set how many LEDC tick each time the gradient lasts
|
||||
* @param duty_cyle_num Set how many LEDC tick each time the gradient lasts
|
||||
*
|
||||
* @param[in] duty_scale : set gradient change amplitude
|
||||
* @param duty_scale Set gradient change amplitude
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG : parameter error
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty, ledc_duty_direction_t gradule_direction,
|
||||
uint32_t step_num, uint32_t duty_cyle_num, uint32_t duty_scale);
|
||||
@@ -249,34 +250,37 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty,
|
||||
/**
|
||||
* @brief register LEDC interrupt handler, the handler is an ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @note
|
||||
* Users should know that which CPU is running and then pick a INUM that is not used by system.
|
||||
* We can find the information of INUM and interrupt level in soc.h.
|
||||
* TODO: to move INUM options to menu_config
|
||||
* @param[in] uint32_t ledc_intr_num : LEDC interrupt number, check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @param[in] void (* fn)(void* ) : interrupt handler function.
|
||||
* @param ledc_intr_num LEDC interrupt number, check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @param fn Interrupt handler function.
|
||||
* @note
|
||||
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
|
||||
* @param[in] void * arg : parameter for handler function
|
||||
* @param arg Parameter for handler function
|
||||
*
|
||||
* @return ESP_OK : success ;
|
||||
* ESP_ERR_INVALID_ARG : function ptr error.
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Function pointer error.
|
||||
*/
|
||||
esp_err_t ledc_isr_register(uint32_t ledc_intr_num, void (*fn)(void*), void * arg);
|
||||
|
||||
/**
|
||||
* @brief configure LEDC settings
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_sel : timer index(0-3), there are 4 timers in LEDC module
|
||||
* @param timer_sel Timer index(0-3), there are 4 timers in LEDC module
|
||||
*
|
||||
* @param[in] div_num : timer clock divide number, the timer clock is divided from the selected clock source
|
||||
* @param div_num Timer clock divide number, the timer clock is divided from the selected clock source
|
||||
*
|
||||
* @param[in] bit_num : the count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1)
|
||||
* @param bit_num The count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1)
|
||||
*
|
||||
* @param[in] clk_src : select LEDC source clock.
|
||||
* @param clk_src Select LEDC source clock.
|
||||
*
|
||||
* @return -1: parameter error
|
||||
* other value: current LEDC duty
|
||||
* @return
|
||||
* - (-1) Parameter error
|
||||
* - Other Current LEDC duty
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src);
|
||||
@@ -284,13 +288,14 @@ esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_
|
||||
/**
|
||||
* @brief reset LEDC timer
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t
|
||||
* @param timer_sel LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_OK: success
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
@@ -298,13 +303,14 @@ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
/**
|
||||
* @brief pause LEDC timer counter
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t
|
||||
* @param timer_sel LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_OK: success
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
@@ -312,13 +318,14 @@ esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
/**
|
||||
* @brief pause LEDC timer resume
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t
|
||||
* @param timer_sel LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_OK: success
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
@@ -326,42 +333,31 @@ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
/**
|
||||
* @brief bind LEDC channel with the selected timer
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
* @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel index(0-7), select from ledc_channel_t
|
||||
* @param channel LEDC channel index(0-7), select from ledc_channel_t
|
||||
*
|
||||
* @param[in] timer_idx : LEDC timer index(0-3), select from ledc_timer_t
|
||||
* @param timer_idx LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_OK: success
|
||||
* @return
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
* - ESP_OK Success
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx);
|
||||
|
||||
/**
|
||||
* @brief Set LEDC output signal to GPIO
|
||||
*
|
||||
* @param[in] gpio_num : GPIO number for LEDC signal output
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel index(0-7), select from ledc_channel_t
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_OK: success
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_set_pin(int gpio_num,ledc_mode_t speed_mode, ledc_channel_t ledc_channel);
|
||||
|
||||
/***************************EXAMPLE**********************************
|
||||
*
|
||||
*
|
||||
* ----------------EXAMPLE OF LEDC SETTING ---------------------
|
||||
* @code{c}
|
||||
* //1. enable LEDC
|
||||
* periph_module_enable(PERIPH_LEDC_MODULE); //enable LEDC module, or you can not set any register of it.
|
||||
* //enable LEDC module, or you can not set any register of it.
|
||||
* periph_module_enable(PERIPH_LEDC_MODULE);
|
||||
* @endcode
|
||||
*
|
||||
* @code{c}
|
||||
* //2. set LEDC timer
|
||||
* ledc_timer_config_t timer_conf = {
|
||||
* .bit_num = LEDC_TIMER_12_BIT, //set timer counter bit number
|
||||
@@ -370,33 +366,41 @@ esp_err_t ledc_set_pin(int gpio_num,ledc_mode_t speed_mode, ledc_channel_t ledc_
|
||||
* .timer_num = LEDC_TIMER_0, //timer number
|
||||
* };
|
||||
* ledc_timer_config(&timer_conf); //setup timer.
|
||||
* @endcode
|
||||
*
|
||||
* @code{c}
|
||||
* //3. set LEDC channel
|
||||
* ledc_channel_config_t ledc_conf = {
|
||||
* .channel = LEDC_CHANNEL_0, //set LEDC channel 0
|
||||
* .duty = 1000, //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1)
|
||||
* .gpio_num = 16, //GPIO number
|
||||
* .intr_type = LEDC_INTR_FADE_END, //GPIO INTR TYPE, as an example, we enable fade_end interrupt here.
|
||||
* .speed_mode = LEDC_HIGH_SPEED_MODE, //set LEDC mode, from ledc_mode_t
|
||||
* .timer_sel = LEDC_TIMER_0, //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same
|
||||
* .channel = LEDC_CHANNEL_0; //set LEDC channel 0
|
||||
* .duty = 1000; //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1)
|
||||
* .gpio_num = 16; //GPIO number
|
||||
* .intr_type = LEDC_INTR_FADE_END; //GPIO INTR TYPE, as an example, we enable fade_end interrupt here.
|
||||
* .speed_mode = LEDC_HIGH_SPEED_MODE; //set LEDC mode, from ledc_mode_t
|
||||
* .timer_sel = LEDC_TIMER_0; //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same
|
||||
* }
|
||||
* ledc_channel_config(&ledc_conf); //setup the configuration
|
||||
*
|
||||
* ----------------EXAMPLE OF SETTING DUTY --- -----------------
|
||||
* @code{c}
|
||||
* uint32_t ledc_channel = LEDC_CHANNEL_0; //LEDC channel(0-73)
|
||||
* uint32_t duty = 2000; //duty range is 0 ~ ((2**bit_num)-1)
|
||||
* LEDC_set_duty(LEDC_HIGH_SPEED_MODE, ledc_channel, duty); //set speed mode, channel, and duty.
|
||||
* ledc_update_duty(LEDC_HIGH_SPEED_MODE, ledc_channel); //after set duty, we need to call ledc_update_duty to update the settings.
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* ----------------EXAMPLE OF LEDC INTERRUPT ------------------
|
||||
* @code{c}
|
||||
* //we have fade_end interrupt and counter overflow interrupt. we just give an example of fade_end interrupt here.
|
||||
* ledc_isr_register(18, ledc_isr_handler, NULL); //hook the isr handler for LEDC interrupt
|
||||
* //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
|
||||
* //NOTE1:user should arrange the INUMs that used, better not to use a same INUM for different interrupt source.
|
||||
* //NOTE2:do not pick the INUM that already occupied by the system.
|
||||
* //NOTE3:refer to soc.h to check which INUMs that can be used.
|
||||
* @endcode
|
||||
* @note
|
||||
* 1. the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
|
||||
* 2. user should arrange the INUMs that used, better not to use a same INUM for different interrupt source.
|
||||
* 3. do not pick the INUM that already occupied by the system.
|
||||
* 4. refer to soc.h to check which INUMs that can be used.
|
||||
*
|
||||
* ----------------EXAMPLE OF INTERRUPT HANDLER ---------------
|
||||
* @code{c}
|
||||
* #include "esp_attr.h"
|
||||
* void IRAM_ATTR ledc_isr_handler(void* arg) //we should add 'IRAM_ATTR' attribution when we declare the isr function
|
||||
* {
|
||||
@@ -408,7 +412,7 @@ esp_err_t ledc_set_pin(int gpio_num,ledc_mode_t speed_mode, ledc_channel_t ledc_
|
||||
*
|
||||
* LEDC.int_clr.val = intr_st; //clear LEDC interrupt status.
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
*--------------------------END OF EXAMPLE --------------------------
|
||||
*/
|
||||
|
@@ -319,6 +319,49 @@ config BROWNOUT_DET_RESETDELAY
|
||||
before trying to restart the chip. You can set the delay here.
|
||||
|
||||
|
||||
choice ESP32_TIME_SYSCALL
|
||||
prompt "Timers used for gettimeofday function"
|
||||
default ESP32_TIME_SYSCALL_USE_RTC_FRC1
|
||||
help
|
||||
This setting defines which hardware timers are used to
|
||||
implement 'gettimeofday' and 'time' functions in C library.
|
||||
|
||||
- If only FRC1 timer is used, gettimeofday will provide time at
|
||||
microsecond resolution. Time will not be preserved when going
|
||||
into deep sleep mode.
|
||||
- If both FRC1 and RTC timers are used, timekeeping will
|
||||
continue in deep sleep. Time will be reported at 1 microsecond
|
||||
resolution.
|
||||
- If only RTC timer is used, timekeeping will continue in
|
||||
deep sleep, but time will be measured at 6.(6) microsecond
|
||||
resolution. Also the gettimeofday function itself may take
|
||||
longer to run.
|
||||
- If no timers are used, gettimeofday and time functions
|
||||
return -1 and set errno to ENOSYS.
|
||||
|
||||
config ESP32_TIME_SYSCALL_USE_RTC
|
||||
bool "RTC"
|
||||
config ESP32_TIME_SYSCALL_USE_RTC_FRC1
|
||||
bool "RTC and FRC1"
|
||||
config ESP32_TIME_SYSCALL_USE_FRC1
|
||||
bool "FRC1"
|
||||
config ESP32_TIME_SYSCALL_USE_NONE
|
||||
bool "None"
|
||||
endchoice
|
||||
|
||||
choice ESP32_RTC_CLOCK_SOURCE
|
||||
prompt "RTC clock source"
|
||||
default ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC
|
||||
help
|
||||
Choose which clock is used as RTC clock source.
|
||||
The only available option for now is to use internal
|
||||
150kHz RC oscillator.
|
||||
|
||||
config ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC
|
||||
bool "Internal RC"
|
||||
config ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
|
||||
bool "External 32kHz crystal"
|
||||
depends on DOCUMENTATION_FOR_RTC_CNTL
|
||||
endchoice
|
||||
|
||||
endmenu
|
||||
|
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/uart.h"
|
||||
#include "rom/rtc.h"
|
||||
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/dport_reg.h"
|
||||
@@ -65,6 +66,8 @@ extern void app_main(void);
|
||||
|
||||
extern int _bss_start;
|
||||
extern int _bss_end;
|
||||
extern int _rtc_bss_start;
|
||||
extern int _rtc_bss_end;
|
||||
extern int _init_start;
|
||||
extern void (*__init_array_start)(void);
|
||||
extern void (*__init_array_end)(void);
|
||||
@@ -95,6 +98,11 @@ void IRAM_ATTR call_start_cpu0()
|
||||
|
||||
memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
|
||||
|
||||
/* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */
|
||||
if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) {
|
||||
memset(&_rtc_bss_start, 0, (&_rtc_bss_end - &_rtc_bss_start) * sizeof(_rtc_bss_start));
|
||||
}
|
||||
|
||||
// Initialize heap allocator
|
||||
heap_alloc_caps_init();
|
||||
|
||||
@@ -161,7 +169,8 @@ void start_cpu0_default(void)
|
||||
#if CONFIG_TASK_WDT
|
||||
esp_task_wdt_init();
|
||||
#endif
|
||||
esp_setup_syscalls();
|
||||
esp_setup_syscall_table();
|
||||
esp_setup_time_syscalls();
|
||||
esp_vfs_dev_uart_register();
|
||||
esp_reent_init(_GLOBAL_REENT);
|
||||
const char* default_uart_dev = "/dev/uart/0";
|
||||
|
@@ -40,8 +40,7 @@ void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub)
|
||||
}
|
||||
|
||||
void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) {
|
||||
//
|
||||
//mmu_init(0);
|
||||
/* Clear MMU for CPU 0 */
|
||||
REG_SET_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR);
|
||||
REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR);
|
||||
}
|
||||
|
@@ -351,7 +351,7 @@ static int gdbReadCommand() {
|
||||
|
||||
|
||||
|
||||
void gdbstubPanicHandler(XtExcFrame *frame) {
|
||||
void esp_gdbstub_panic_handler(XtExcFrame *frame) {
|
||||
dumpHwToRegfile(frame);
|
||||
//Make sure txd/rxd are enabled
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
|
||||
|
@@ -20,22 +20,21 @@
|
||||
//and all variables in shared RAM. These macros can be used to redirect
|
||||
//particular functions/variables to other memory regions.
|
||||
|
||||
// Forces code into IRAM instead of flash
|
||||
// Forces code into IRAM instead of flash.
|
||||
#define IRAM_ATTR __attribute__((section(".iram1")))
|
||||
|
||||
// Forces data into DRAM instead of flash
|
||||
#define DRAM_ATTR __attribute__((section(".dram1")))
|
||||
|
||||
// Forces code into RTC fast memory
|
||||
// Forces code into RTC fast memory. See "docs/deep-sleep-stub.rst"
|
||||
#define RTC_IRAM_ATTR __attribute__((section(".rtc.text")))
|
||||
|
||||
// Forces data into RTC slow memory
|
||||
// Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst"
|
||||
// Any variable marked with this attribute will keep its value
|
||||
// during a deep sleep / wake cycle.
|
||||
#define RTC_DATA_ATTR __attribute__((section(".rtc.data")))
|
||||
|
||||
// Forces read-only data into RTC slow memory
|
||||
// Makes constant data available to RTC wake stubs (see esp_deepsleep.h)
|
||||
// Forces read-only data into RTC slow memory. See "docs/deep-sleep-stub.rst"
|
||||
#define RTC_RODATA_ATTR __attribute__((section(".rtc.rodata")))
|
||||
|
||||
#endif /* __ESP_ATTR_H__ */
|
||||
|
@@ -54,37 +54,7 @@ void system_deep_sleep(uint64_t time_in_us);
|
||||
* to run code immediately when the chip wakes from
|
||||
* sleep.
|
||||
*
|
||||
* For example:
|
||||
* @code
|
||||
* void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
|
||||
* esp_default_wake_deep_sleep();
|
||||
* // Add additional functionality here
|
||||
* }
|
||||
*
|
||||
* (Implementing this function is not required for normal operation,
|
||||
* in the usual case your app will start normally when waking from
|
||||
* deep sleep.)
|
||||
*
|
||||
* esp_wake_deep_sleep() functionality is limited:
|
||||
*
|
||||
* - Runs immediately on wake, so most of the SoC is freshly reset -
|
||||
* flash is unmapped and hardware is otherwise uninitialised.
|
||||
*
|
||||
* - Can only call functions implemented in ROM, or marked RTC_IRAM_ATTR.
|
||||
*
|
||||
* - Static variables marked RTC_DATA_ATTR will have initial values on
|
||||
* cold boot, and maintain these values between sleep/wake cycles.
|
||||
*
|
||||
* - Read-only data should be marked RTC_RODATA_ATTR. Strings must be
|
||||
* declared as variables also using RTC_RODATA_ATTR, like this:
|
||||
* RTC_RODATA_ATTR const char message[] = "Hello from very early boot!\n";
|
||||
*
|
||||
* - Any other static memory will not be initialised (either to zero,
|
||||
* or to any predefined value).
|
||||
*
|
||||
*
|
||||
* - If you implement your own stub, the first call the stub makes
|
||||
should be to esp_default_wake_deep_sleep().
|
||||
* See docs/deep-sleep-stub.rst for details.
|
||||
*/
|
||||
void esp_wake_deep_sleep(void);
|
||||
|
||||
@@ -115,9 +85,7 @@ esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void);
|
||||
|
||||
/* The default esp-idf-provided esp_wake_deep_sleep() stub.
|
||||
|
||||
If you replace esp_wake_deep_sleep() in your program, or use
|
||||
esp_set_deep_sleep_wake_stub(), then it is recommended you call
|
||||
esp_default_wake_deep_sleep() as the first function in your stub.
|
||||
See docs/deep-sleep-stub.rst for details.
|
||||
*/
|
||||
void esp_default_wake_deep_sleep(void);
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#define __ESP_SYSTEM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_deepsleep.h"
|
||||
|
49
components/esp32/include/soc/frc_timer_reg.h
Normal file
49
components/esp32/include/soc/frc_timer_reg.h
Normal file
@@ -0,0 +1,49 @@
|
||||
// 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 _SOC_FRC_TIMER_REG_H_
|
||||
#define _SOC_FRC_TIMER_REG_H_
|
||||
|
||||
#include "soc.h"
|
||||
|
||||
/**
|
||||
* These are the register definitions for "legacy" timers
|
||||
*/
|
||||
|
||||
#define REG_FRC_TIMER_BASE(i) (DR_REG_FRC_TIMER_BASE + i*0x20)
|
||||
|
||||
#define FRC_TIMER_LOAD_REG(i) (REG_FRC_TIMER_BASE(i) + 0x0) // timer load value (23 bit for i==0, 32 bit for i==1)
|
||||
#define FRC_TIMER_LOAD_VALUE(i) ((i == 0)?0x007FFFFF:0xffffffff)
|
||||
#define FRC_TIMER_LOAD_VALUE_S 0
|
||||
|
||||
#define FRC_TIMER_COUNT_REG(i) (REG_FRC_TIMER_BASE(i) + 0x4) // timer count value (23 bit for i==0, 32 bit for i==1)
|
||||
#define FRC_TIMER_COUNT ((i == 0)?0x007FFFFF:0xffffffff)
|
||||
#define FRC_TIMER_COUNT_S 0
|
||||
|
||||
#define FRC_TIMER_CTRL_REG(i) (REG_FRC_TIMER_BASE(i) + 0x8)
|
||||
#define FRC_TIMER_INT_ENABLE (BIT(8)) // enable interrupt
|
||||
#define FRC_TIMER_ENABLE (BIT(7)) // enable timer
|
||||
#define FRC_TIMER_AUTOLOAD (BIT(6)) // enable autoload
|
||||
#define FRC_TIMER_PRESCALER 0x00000007 // 0: divide by 1, 2: divide by 16, 4: divide by 256
|
||||
#define FRC_TIMER_PRESCALER_S 1
|
||||
#define FRC_TIMER_EDGE_INT (BIT(0)) // 0: level, 1: edge
|
||||
|
||||
#define FRC_TIMER_INT_REG(i) (REG_FRC_TIMER_BASE(i) + 0xC)
|
||||
#define FRC_TIMER_INT_CLR (BIT(0)) // clear interrupt
|
||||
|
||||
#define FRC_TIMER_ALARM_REG(i) (REG_FRC_TIMER_BASE(i) + 0x10) // timer alarm value; register only present for i == 1
|
||||
#define FRC_TIMER_ALARM 0xFFFFFFFF
|
||||
#define FRC_TIMER_ALARM_S 0
|
||||
|
||||
#endif //_SOC_FRC_TIMER_REG_H_
|
@@ -239,6 +239,9 @@
|
||||
#define RTC_CNTL_TIME_VALID_V 0x1
|
||||
#define RTC_CNTL_TIME_VALID_S 30
|
||||
|
||||
/* frequency of RTC slow clock, Hz */
|
||||
#define RTC_CTNL_SLOWCLK_FREQ 150000
|
||||
|
||||
#define RTC_CNTL_TIME0_REG (DR_REG_RTCCNTL_BASE + 0x10)
|
||||
/* RTC_CNTL_TIME_LO : RO ;bitpos:[31:0] ;default: 32'h0 ; */
|
||||
/*description: RTC timer low 32 bits*/
|
||||
|
@@ -148,6 +148,7 @@
|
||||
#define DR_REG_GPIO_SD_BASE 0x3ff44f00
|
||||
#define DR_REG_FE2_BASE 0x3ff45000
|
||||
#define DR_REG_FE_BASE 0x3ff46000
|
||||
#define DR_REG_FRC_TIMER_BASE 0x3ff47000
|
||||
#define DR_REG_RTCCNTL_BASE 0x3ff48000
|
||||
#define DR_REG_RTCIO_BASE 0x3ff48400
|
||||
#define DR_REG_SARADC_BASE 0x3ff48800
|
||||
@@ -281,9 +282,9 @@
|
||||
* 19 2 extern level
|
||||
* 20 2 extern level
|
||||
* 21 2 extern level
|
||||
* 22 3 extern edge
|
||||
* 22 3 extern edge FRC1 timer
|
||||
* 23 3 extern level
|
||||
* 24 4 extern level
|
||||
* 24 4 extern level TG1_WDT
|
||||
* 25 4 extern level Reserved Reserved
|
||||
* 26 5 extern level Reserved Reserved
|
||||
* 27 3 extern level Reserved Reserved
|
||||
@@ -301,8 +302,10 @@
|
||||
#define ETS_T0_WDT_INUM 3
|
||||
#define ETS_WBB_INUM 4
|
||||
#define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/
|
||||
#define ETS_FRC1_INUM 22
|
||||
#define ETS_T1_WDT_INUM 24
|
||||
|
||||
//CPU0 Intrrupt number used in ROM, should be cancelled in SDK
|
||||
//CPU0 Interrupt number used in ROM, should be cancelled in SDK
|
||||
#define ETS_SLC_INUM 1
|
||||
#define ETS_UART0_INUM 5
|
||||
#define ETS_UART1_INUM 5
|
||||
|
@@ -3,6 +3,36 @@ ENTRY(call_start_cpu0);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* RTC fast memory holds RTC wake stub code,
|
||||
including from any source file named rtc_wake_stub*.c
|
||||
*/
|
||||
.rtc.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rtc.literal .rtc.text)
|
||||
*rtc_wake_stub*.o(.literal .text .literal.* .text.*)
|
||||
} >rtc_iram_seg
|
||||
|
||||
/* RTC slow memory holds RTC wake stub
|
||||
data/rodata, including from any source file
|
||||
named rtc_wake_stub*.c
|
||||
*/
|
||||
.rtc.data :
|
||||
{
|
||||
*(.rtc.data)
|
||||
*(.rtc.rodata)
|
||||
*rtc_wake_stub*.o(.data .rodata .data.* .rodata.* .bss .bss.*)
|
||||
} > rtc_slow_seg
|
||||
|
||||
/* RTC bss, from any source file named rtc_wake_stub*.c */
|
||||
.rtc.bss (NOLOAD) :
|
||||
{
|
||||
_rtc_bss_start = ABSOLUTE(.);
|
||||
*rtc_wake_stub*.o(.bss .bss.*)
|
||||
*rtc_wake_stub*.o(COMMON)
|
||||
_rtc_bss_end = ABSOLUTE(.);
|
||||
} > rtc_slow_seg
|
||||
|
||||
/* Send .iram0 code to iram */
|
||||
.iram0.vectors :
|
||||
{
|
||||
@@ -155,16 +185,4 @@ SECTIONS
|
||||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
} >iram0_2_seg
|
||||
|
||||
.rtc.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rtc.literal .rtc.text)
|
||||
} >rtc_iram_seg
|
||||
|
||||
.rtc.data :
|
||||
{
|
||||
*(.rtc.data)
|
||||
*(.rtc.rodata)
|
||||
} > rtc_slow_seg
|
||||
}
|
||||
|
Submodule components/esp32/lib updated: 9d18fd1a8f...b3090d8854
61
components/log/README.rst
Normal file
61
components/log/README.rst
Normal file
@@ -0,0 +1,61 @@
|
||||
Logging library
|
||||
===============
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Log library has two ways of managing log verbosity: compile time, set via menuconfig; and runtime, using ``esp_log_set_level`` function.
|
||||
|
||||
At compile time, filtering is done using ``CONFIG_LOG_DEFAULT_LEVEL`` macro, set via menuconfig. All logging statments for levels higher than ``CONFIG_LOG_DEFAULT_LEVEL`` will be removed by the preprocessor.
|
||||
|
||||
At run time, all logs below ``CONFIG_LOG_DEFAULT_LEVEL`` are enabled by default. ``esp_log_set_level`` function may be used to set logging level per module. Modules are identified by their tags, which are human-readable ASCII zero-terminated strings.
|
||||
|
||||
How to use this library
|
||||
-----------------------
|
||||
|
||||
In each C file which uses logging functionality, define TAG variable like this:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static const char* TAG = "MyModule";
|
||||
|
||||
then use one of logging macros to produce output, e.g:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
ESP_LOGW(TAG, "Baud rate error %.1f%%. Requested: %d baud, actual: %d baud", error * 100, baud_req, baud_real);
|
||||
|
||||
Several macros are available for different verbosity levels:
|
||||
|
||||
* ``ESP_LOGE`` - error
|
||||
* ``ESP_LOGW`` - warning
|
||||
* ``ESP_LOGI`` - info
|
||||
* ``ESP_LOGD`` - debug
|
||||
* ``ESP_LOGV`` - verbose
|
||||
|
||||
Additionally there is an _EARLY_ variant for each of these macros (e.g. ``ESP_EARLY_LOGE`` ).These variants can run in startup code, before heap allocator and syscalls have been initialized. When compiling bootloader, normal ``ESP_LOGx`` macros fall back to the same implementation as ``ESP_EARLY_LOGx`` macros. So the only place where ``ESP_EARLY_LOGx`` have to be used explicitly is the early startup code, such as heap allocator initialization code.
|
||||
|
||||
(Note that such distinction would not have been necessary if we would have an ``ets_vprintf`` function in the ROM. Then it would be possible to switch implementation from _EARLY_ version to normal version on the fly. Unfortunately, ``ets_vprintf`` in ROM has been inlined by the compiler into ``ets_printf``, so it is not accessible outside.)
|
||||
|
||||
To override default verbosity level at file or component scope, define ``LOG_LOCAL_LEVEL`` macro. At file scope, define it before including ``esp_log.h``, e.g.:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
At component scope, define it in component makefile:
|
||||
|
||||
.. code-block:: make
|
||||
|
||||
CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
|
||||
|
||||
To configure logging output per module at runtime, add calls to ``esp_log_set_level`` function:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
esp_log_set_level("*", ESP_LOG_ERROR); // set all components to ERROR level
|
||||
esp_log_set_level("wifi", ESP_LOG_WARN); // enable WARN logs from WiFi stack
|
||||
esp_log_set_level("dhcpc", ESP_LOG_INFO); // enable INFO logs from DHCP client
|
||||
|
@@ -24,76 +24,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Logging library
|
||||
*
|
||||
* Log library has two ways of managing log verbosity: compile time, set via
|
||||
* menuconfig, and runtime, using esp_log_set_level function.
|
||||
*
|
||||
* At compile time, filtering is done using CONFIG_LOG_DEFAULT_LEVEL macro, set via
|
||||
* menuconfig. All logging statments for levels higher than CONFIG_LOG_DEFAULT_LEVEL
|
||||
* will be removed by the preprocessor.
|
||||
*
|
||||
* At run time, all logs below CONFIG_LOG_DEFAULT_LEVEL are enabled by default.
|
||||
* esp_log_set_level function may be used to set logging level per module.
|
||||
* Modules are identified by their tags, which are human-readable ASCII
|
||||
* zero-terminated strings.
|
||||
*
|
||||
* How to use this library:
|
||||
*
|
||||
* In each C file which uses logging functionality, define TAG variable like this:
|
||||
*
|
||||
* static const char* TAG = "MyModule";
|
||||
*
|
||||
* then use one of logging macros to produce output, e.g:
|
||||
*
|
||||
* ESP_LOGW(TAG, "Baud rate error %.1f%%. Requested: %d baud, actual: %d baud", error * 100, baud_req, baud_real);
|
||||
*
|
||||
* Several macros are available for different verbosity levels:
|
||||
*
|
||||
* ESP_LOGE — error
|
||||
* ESP_LOGW — warning
|
||||
* ESP_LOGI — info
|
||||
* ESP_LOGD - debug
|
||||
* ESP_LOGV - verbose
|
||||
*
|
||||
* Additionally there is an _EARLY_ variant for each of these macros (e.g. ESP_EARLY_LOGE).
|
||||
* These variants can run in startup code, before heap allocator and syscalls
|
||||
* have been initialized.
|
||||
* When compiling bootloader, normal ESP_LOGx macros fall back to the same implementation
|
||||
* as ESP_EARLY_LOGx macros. So the only place where ESP_EARLY_LOGx have to be used explicitly
|
||||
* is the early startup code, such as heap allocator initialization code.
|
||||
*
|
||||
* (Note that such distinction would not have been necessary if we would have an
|
||||
* ets_vprintf function in the ROM. Then it would be possible to switch implementation
|
||||
* from _EARLY version to normal version on the fly. Unfortunately, ets_vprintf in ROM
|
||||
* has been inlined by the compiler into ets_printf, so it is not accessible outside.)
|
||||
*
|
||||
* To override default verbosity level at file or component scope, define LOG_LOCAL_LEVEL macro.
|
||||
* At file scope, define it before including esp_log.h, e.g.:
|
||||
*
|
||||
* #define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
|
||||
* #include "esp_log.h"
|
||||
*
|
||||
* At component scope, define it in component makefile:
|
||||
*
|
||||
* CFLAGS += -D LOG_LOCAL_LEVEL=ESP_LOG_DEBUG
|
||||
*
|
||||
* To configure logging output per module at runtime, add calls to esp_log_set_level function:
|
||||
*
|
||||
* esp_log_set_level("*", ESP_LOG_ERROR); // set all components to ERROR level
|
||||
* esp_log_set_level("wifi", ESP_LOG_WARN); // enable WARN logs from WiFi stack
|
||||
* esp_log_set_level("dhcpc", ESP_LOG_INFO); // enable INFO logs from DHCP client
|
||||
* @brief Log level
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
typedef enum {
|
||||
ESP_LOG_NONE, // No log output
|
||||
ESP_LOG_ERROR, // Critical errors, software module can not recover on its own
|
||||
ESP_LOG_WARN, // Error conditions from which recovery measures have been taken
|
||||
ESP_LOG_INFO, // Information messages which describe normal flow of events
|
||||
ESP_LOG_DEBUG, // Extra information which is not necessary for normal use (values, pointers, sizes, etc).
|
||||
ESP_LOG_VERBOSE // Bigger chunks of debugging information, or frequent messages which can potentially flood the output.
|
||||
ESP_LOG_NONE, /*!< No log output */
|
||||
ESP_LOG_ERROR, /*!< Critical errors, software module can not recover on its own */
|
||||
ESP_LOG_WARN, /*!< Error conditions from which recovery measures have been taken */
|
||||
ESP_LOG_INFO, /*!< Information messages which describe normal flow of events */
|
||||
ESP_LOG_DEBUG, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */
|
||||
ESP_LOG_VERBOSE /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */
|
||||
} esp_log_level_t;
|
||||
|
||||
typedef int (*vprintf_like_t)(const char *, va_list);
|
||||
@@ -120,17 +60,6 @@ void esp_log_level_set(const char* tag, esp_log_level_t level);
|
||||
*/
|
||||
void esp_log_set_vprintf(vprintf_like_t func);
|
||||
|
||||
/**
|
||||
* @brief Write message into the log
|
||||
*
|
||||
* This function is not intended to be used directly. Instead, use one of
|
||||
* ESP_LOGE, ESP_LOGW, ESP_LOGI, ESP_LOGD, ESP_LOGV macros.
|
||||
*
|
||||
* This function or these macros should not be used from an interrupt.
|
||||
*/
|
||||
void esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function which returns timestamp to be used in log output
|
||||
*
|
||||
@@ -143,7 +72,17 @@ void esp_log_write(esp_log_level_t level, const char* tag, const char* format, .
|
||||
*
|
||||
* @return timestamp, in milliseconds
|
||||
*/
|
||||
uint32_t esp_log_timestamp();
|
||||
uint32_t esp_log_timestamp(void);
|
||||
|
||||
/**
|
||||
* @brief Write message into the log
|
||||
*
|
||||
* This function is not intended to be used directly. Instead, use one of
|
||||
* ESP_LOGE, ESP_LOGW, ESP_LOGI, ESP_LOGD, ESP_LOGV macros.
|
||||
*
|
||||
* This function or these macros should not be used from an interrupt.
|
||||
*/
|
||||
void esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
|
||||
|
||||
#if CONFIG_LOG_COLORS
|
||||
|
@@ -24,6 +24,15 @@ config LWIP_SO_REUSE
|
||||
Enabling this option allows binding to a port which remains in
|
||||
TIME_WAIT.
|
||||
|
||||
config LWIP_DHCP_MAX_NTP_SERVERS
|
||||
int "Maximum number of NTP servers"
|
||||
default 1
|
||||
range 1 16
|
||||
help
|
||||
Set maxumum number of NTP servers used by LwIP SNTP module.
|
||||
First argument of sntp_setserver/sntp_setservername functions
|
||||
is limited to this value.
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
|
@@ -382,31 +382,6 @@ static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr,
|
||||
static void lwip_socket_drop_registered_memberships(int s);
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
#if ESP_LWIP
|
||||
#include "esp_wifi_internal.h"
|
||||
#include "esp_system.h"
|
||||
|
||||
/* Please be notified that this flow control is just a workaround for fixing wifi Q full issue.
|
||||
* Under UDP/TCP pressure test, we found that the sockets may cause wifi tx queue full if the socket
|
||||
* sending speed is faster than the wifi sending speed, it will finally cause the packet to be dropped
|
||||
* in wifi layer, it's not acceptable in some application. That's why we introdue the tx flow control here.
|
||||
* However, current solution is just a workaround, we need to consider the return value of wifi tx interface,
|
||||
* and feedback the return value to lwip and let lwip do the flow control itself.
|
||||
*/
|
||||
static inline void esp32_tx_flow_ctrl(void)
|
||||
{
|
||||
uint8_t _wait_delay = 1;
|
||||
|
||||
while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_internal_tx_is_stop()){
|
||||
vTaskDelay(_wait_delay/portTICK_RATE_MS);
|
||||
if (_wait_delay < 64) _wait_delay *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#define esp32_tx_flow_ctrl()
|
||||
#endif
|
||||
|
||||
/** The global array of available sockets */
|
||||
static struct lwip_sock sockets[NUM_SOCKETS];
|
||||
#if ESP_THREAD_SAFE
|
||||
@@ -1208,8 +1183,6 @@ lwip_send(int s, const void *data, size_t size, int flags)
|
||||
#endif /* (LWIP_UDP || LWIP_RAW) */
|
||||
}
|
||||
|
||||
esp32_tx_flow_ctrl();
|
||||
|
||||
write_flags = NETCONN_COPY |
|
||||
((flags & MSG_MORE) ? NETCONN_MORE : 0) |
|
||||
((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0);
|
||||
@@ -1391,8 +1364,6 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
||||
#endif /* LWIP_TCP */
|
||||
}
|
||||
|
||||
esp32_tx_flow_ctrl();
|
||||
|
||||
if ((to != NULL) && !SOCK_ADDR_TYPE_MATCH(to, sock)) {
|
||||
/* sockaddr does not match socket type (IPv4/IPv6) */
|
||||
sock_set_errno(sock, err_to_errno(ERR_VAL));
|
||||
|
@@ -33,6 +33,8 @@
|
||||
#define __LWIPOPTS_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "esp_task.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
@@ -523,7 +525,6 @@ extern unsigned long os_random(void);
|
||||
#define ESP_IP4_ATON 1
|
||||
#define ESP_LIGHT_SLEEP 1
|
||||
|
||||
|
||||
#define TCP_WND_DEFAULT (4*TCP_MSS)
|
||||
#define TCP_SND_BUF_DEFAULT (2*TCP_MSS)
|
||||
|
||||
@@ -550,12 +551,25 @@ extern unsigned char misc_prof_get_tcp_snd_buf(void);
|
||||
#define CHECKSUM_CHECK_UDP 0
|
||||
#define CHECKSUM_CHECK_IP 0
|
||||
|
||||
#define HEAP_HIGHWAT 20*1024
|
||||
|
||||
#define LWIP_NETCONN_FULLDUPLEX 1
|
||||
#define LWIP_NETCONN_SEM_PER_THREAD 1
|
||||
|
||||
#define LWIP_DHCP_MAX_NTP_SERVERS CONFIG_LWIP_DHCP_MAX_NTP_SERVERS
|
||||
#define LWIP_TIMEVAL_PRIVATE 0
|
||||
|
||||
#define SNTP_SET_SYSTEM_TIME_US(sec, us) \
|
||||
do { \
|
||||
struct timeval tv = { .tv_sec = sec, .tv_usec = us }; \
|
||||
settimeofday(&tv, NULL); \
|
||||
} while (0);
|
||||
|
||||
#define SNTP_GET_SYSTEM_TIME(sec, us) \
|
||||
do { \
|
||||
struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; \
|
||||
gettimeofday(&tv, NULL); \
|
||||
(sec) = tv.tv_sec; \
|
||||
(us) = tv.tv_usec; \
|
||||
} while (0);
|
||||
|
||||
#define SOC_SEND_LOG //printf
|
||||
|
||||
|
@@ -142,16 +142,13 @@ low_level_output(struct netif *netif, struct pbuf *p)
|
||||
}
|
||||
}
|
||||
|
||||
esp_wifi_internal_tx(wifi_if, q->payload, pbuf_x_len);
|
||||
return ERR_OK;
|
||||
|
||||
return esp_wifi_internal_tx(wifi_if, q->payload, pbuf_x_len);
|
||||
#else
|
||||
for(q = p; q != NULL; q = q->next) {
|
||||
esp_wifi_internal_tx(wifi_if, q->payload, q->len);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ERR_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -31,7 +31,13 @@ void esp_reent_init(struct _reent* r);
|
||||
* Called from the startup code, not intended to be called from application
|
||||
* code.
|
||||
*/
|
||||
void esp_setup_syscalls();
|
||||
void esp_setup_syscall_table();
|
||||
|
||||
/**
|
||||
* Initialize hardware timer used as time source for newlib time functions.
|
||||
*
|
||||
* Called from the startup code, not intended to be called from application.
|
||||
*/
|
||||
void esp_setup_time_syscalls();
|
||||
|
||||
#endif //__ESP_NEWLIB_H__
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <sys/reent.h>
|
||||
#include "rom/libc_stubs.h"
|
||||
#include "esp_vfs.h"
|
||||
#include "esp_newlib.h"
|
||||
|
||||
static struct _reent s_reent;
|
||||
|
||||
@@ -79,7 +80,7 @@ static struct syscall_stub_table s_stub_table = {
|
||||
._scanf_float = &_scanf_float,
|
||||
};
|
||||
|
||||
void esp_setup_syscalls()
|
||||
void esp_setup_syscall_table()
|
||||
{
|
||||
syscall_table_ptr_pro = &s_stub_table;
|
||||
syscall_table_ptr_app = &s_stub_table;
|
||||
|
@@ -14,22 +14,169 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <reent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/reent.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/lock.h>
|
||||
#include "esp_attr.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/frc_timer_reg.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/task.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC ) || defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 )
|
||||
#define WITH_RTC 1
|
||||
#endif
|
||||
|
||||
clock_t _times_r(struct _reent *r, struct tms *ptms)
|
||||
#if defined( CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 ) || defined( CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 )
|
||||
#define WITH_FRC1 1
|
||||
#endif
|
||||
|
||||
#ifdef WITH_RTC
|
||||
static uint64_t get_rtc_time_us()
|
||||
{
|
||||
__errno_r(r) = ENOSYS;
|
||||
return (clock_t) -1;
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE_M);
|
||||
while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID_M) == 0) {
|
||||
;
|
||||
}
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE_M);
|
||||
uint64_t low = READ_PERI_REG(RTC_CNTL_TIME0_REG);
|
||||
uint64_t high = READ_PERI_REG(RTC_CNTL_TIME1_REG);
|
||||
uint64_t ticks = (high << 32) | low;
|
||||
return ticks * 100 / (RTC_CTNL_SLOWCLK_FREQ / 10000); // scale RTC_CTNL_SLOWCLK_FREQ to avoid overflow
|
||||
}
|
||||
#endif // WITH_RTC
|
||||
|
||||
|
||||
// time from Epoch to the first boot time
|
||||
#ifdef WITH_RTC
|
||||
static RTC_DATA_ATTR struct timeval s_boot_time;
|
||||
#else
|
||||
static struct timeval s_boot_time;
|
||||
#endif
|
||||
static _lock_t s_boot_time_lock;
|
||||
|
||||
|
||||
#ifdef WITH_FRC1
|
||||
#define FRC1_PRESCALER 16
|
||||
#define FRC1_PRESCALER_CTL 2
|
||||
#define FRC1_TICK_FREQ (APB_CLK_FREQ / FRC1_PRESCALER)
|
||||
#define FRC1_TICKS_PER_US (FRC1_TICK_FREQ / 1000000)
|
||||
#define FRC1_ISR_PERIOD_US (FRC_TIMER_LOAD_VALUE(0) / FRC1_TICKS_PER_US)
|
||||
// Counter frequency will be APB_CLK_FREQ / 16 = 5 MHz
|
||||
// 1 tick = 0.2 us
|
||||
// Timer has 23 bit counter, so interrupt will fire each 1677721.6 microseconds.
|
||||
// This is not a whole number, so timer will drift by 0.3 ppm due to rounding error.
|
||||
|
||||
static volatile uint64_t s_microseconds = 0;
|
||||
|
||||
static void IRAM_ATTR frc_timer_isr()
|
||||
{
|
||||
WRITE_PERI_REG(FRC_TIMER_INT_REG(0), FRC_TIMER_INT_CLR);
|
||||
s_microseconds += FRC1_ISR_PERIOD_US;
|
||||
}
|
||||
|
||||
// TODO: read time from RTC
|
||||
int _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz)
|
||||
#endif // WITH_FRC1
|
||||
|
||||
void esp_setup_time_syscalls()
|
||||
{
|
||||
#if defined( WITH_FRC1 )
|
||||
#if defined( WITH_RTC )
|
||||
// initialize time from RTC clock
|
||||
s_microseconds = get_rtc_time_us();
|
||||
#endif //WITH_RTC
|
||||
|
||||
// set up timer
|
||||
WRITE_PERI_REG(FRC_TIMER_CTRL_REG(0), \
|
||||
FRC_TIMER_AUTOLOAD | \
|
||||
(FRC1_PRESCALER_CTL << FRC_TIMER_PRESCALER_S) | \
|
||||
FRC_TIMER_EDGE_INT);
|
||||
|
||||
WRITE_PERI_REG(FRC_TIMER_LOAD_REG(0), FRC_TIMER_LOAD_VALUE(0));
|
||||
SET_PERI_REG_MASK(FRC_TIMER_CTRL_REG(0),
|
||||
FRC_TIMER_ENABLE | \
|
||||
FRC_TIMER_INT_ENABLE);
|
||||
intr_matrix_set(xPortGetCoreID(), ETS_TIMER1_INTR_SOURCE, ETS_FRC1_INUM);
|
||||
xt_set_interrupt_handler(ETS_FRC1_INUM, &frc_timer_isr, NULL);
|
||||
xt_ints_on(1 << ETS_FRC1_INUM);
|
||||
#endif // WITH_FRC1
|
||||
}
|
||||
|
||||
clock_t IRAM_ATTR _times_r(struct _reent *r, struct tms *ptms)
|
||||
{
|
||||
clock_t t = xTaskGetTickCount() * (portTICK_PERIOD_MS * CLK_TCK / 1000);
|
||||
ptms->tms_cstime = t;
|
||||
ptms->tms_cutime = 0;
|
||||
ptms->tms_stime = t;
|
||||
ptms->tms_utime = 0;
|
||||
struct timeval tv = {0, 0};
|
||||
_gettimeofday_r(r, &tv, NULL);
|
||||
return (clock_t) tv.tv_sec;
|
||||
}
|
||||
|
||||
static uint64_t get_time_since_boot()
|
||||
{
|
||||
uint64_t microseconds = 0;
|
||||
#ifdef WITH_FRC1
|
||||
uint32_t timer_ticks_before = READ_PERI_REG(FRC_TIMER_COUNT_REG(0));
|
||||
microseconds = s_microseconds;
|
||||
uint32_t timer_ticks_after = READ_PERI_REG(FRC_TIMER_COUNT_REG(0));
|
||||
if (timer_ticks_after > timer_ticks_before) {
|
||||
// overflow happened at some point between getting
|
||||
// timer_ticks_before and timer_ticks_after
|
||||
// microseconds value is ambiguous, get a new one
|
||||
microseconds = s_microseconds;
|
||||
}
|
||||
microseconds += (FRC_TIMER_LOAD_VALUE(0) - timer_ticks_after) / FRC1_TICKS_PER_US;
|
||||
#elif defined(WITH_RTC)
|
||||
microseconds = get_rtc_time_us();
|
||||
#endif
|
||||
return microseconds;
|
||||
}
|
||||
|
||||
int IRAM_ATTR _gettimeofday_r(struct _reent *r, struct timeval *tv, void *tz)
|
||||
{
|
||||
(void) tz;
|
||||
#if defined( WITH_FRC1 ) || defined( WITH_RTC )
|
||||
uint64_t microseconds = get_time_since_boot();
|
||||
if (tv) {
|
||||
_lock_acquire(&s_boot_time_lock);
|
||||
microseconds += s_boot_time.tv_usec;
|
||||
tv->tv_sec = s_boot_time.tv_sec + microseconds / 1000000;
|
||||
tv->tv_usec = microseconds % 1000000;
|
||||
_lock_release(&s_boot_time_lock);
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
__errno_r(r) = ENOSYS;
|
||||
return -1;
|
||||
#endif // defined( WITH_FRC1 ) || defined( WITH_RTC )
|
||||
}
|
||||
|
||||
int settimeofday(const struct timeval *tv, const struct timezone *tz)
|
||||
{
|
||||
(void) tz;
|
||||
#if defined( WITH_FRC1 ) || defined( WITH_RTC )
|
||||
if (tv) {
|
||||
_lock_acquire(&s_boot_time_lock);
|
||||
uint64_t now = ((uint64_t) tv->tv_sec) * 1000000LL + tv->tv_usec;
|
||||
uint64_t since_boot = get_time_since_boot();
|
||||
uint64_t boot_time = now - since_boot;
|
||||
|
||||
s_boot_time.tv_sec = boot_time / 1000000;
|
||||
s_boot_time.tv_usec = boot_time % 1000000;
|
||||
_lock_release(&s_boot_time_lock);
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
__errno_r(r) = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
@@ -7,14 +7,14 @@ Introduction
|
||||
Non-volatile storage (NVS) library is designed to store key-value pairs in flash. This sections introduces some concepts used by NVS.
|
||||
|
||||
Underlying storage
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Currently NVS uses a portion of main flash memory through ``spi_flash_{read|write|erase}`` APIs. The range of flash sectors to be used by the library is provided to ``nvs_flash_init`` function.
|
||||
|
||||
Future versions of this library may add other storage backends to keep data in another flash chip (SPI or I2C), RTC, FRAM, etc.
|
||||
|
||||
Keys and values
|
||||
~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
NVS operates on key-value pairs. Keys are ASCII strings, maximum key length is currently 15 characters. Values can have one of the following types:
|
||||
|
||||
@@ -32,12 +32,12 @@ Keys are required to be unique. Writing a value for a key which already exists b
|
||||
Data type check is also performed when reading a value. An error is returned if data type of read operation doesn’t match the data type of the value.
|
||||
|
||||
Namespaces
|
||||
~~~~~~~~~~
|
||||
^^^^^^^^^^
|
||||
|
||||
To mitigate potential conflicts in key names between different components, NVS assigns each key-value pair to one of namespaces. Namespace names follow the same rules as key names, i.e. 15 character maximum length. Namespace name is specified in the ``nvs_open`` call. This call returns an opaque handle, which is used in subsequent calls to ``nvs_read_*``, ``nvs_write_*``, and ``nvs_commit`` functions. This way, handle is associated with a namespace, and key names will not collide with same names in other namespaces.
|
||||
|
||||
Security, tampering, and robustness
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
NVS library doesn't implement tamper prevention measures. It is possible for anyone with physical access to the flash chip to alter, erase, or add key-value pairs.
|
||||
|
||||
@@ -59,12 +59,12 @@ Internals
|
||||
---------
|
||||
|
||||
Log of key-value pairs
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
NVS stores key-value pairs sequentially, with new key-value pairs being added at the end. When a value of any given key has to be updated, new key-value pair is added at the end of the log and old key-value pair is marked as erased.
|
||||
|
||||
Pages and entries
|
||||
~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
NVS library uses two main entities in its operation: pages and entries. Page is a logical structure which stores a portion of the overall log. Logical page corresponds to one physical sector of flash memory. Pages which are in use have a *sequence number* associated with them. Sequence numbers impose an ordering on pages. Higher sequence numbers correspond to pages which were created later. Each page can be in one of the following states:
|
||||
|
||||
@@ -101,7 +101,7 @@ Mapping from flash sectors to logical pages doesn't have any particular order. L
|
||||
+----------+ +----------+ +----------+ +----------+
|
||||
|
||||
Structure of a page
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
For now we assume that flash sector size is 4096 bytes and that ESP32 flash encryption hardware operates on 32-byte blocks. It is possible to introduce some settings configurable at compile-time (e.g. via menuconfig) to accommodate flash chips with different sector sizes (although it is not clear if other components in the system, e.g. SPI flash driver and SPI flash cache can support these other sizes).
|
||||
|
||||
@@ -133,7 +133,7 @@ CRC32 value in header is calculated over the part which doesn't include state va
|
||||
The following sections describe structure of entry state bitmap and entry itself.
|
||||
|
||||
Entry and entry state bitmap
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Each entry can be in one of the following three states. Each state is represented with two bits in the entry state bitmap. Final four bits in the bitmap (256 - 2 * 126) are unused.
|
||||
|
||||
@@ -148,7 +148,7 @@ Erased (2'b00)
|
||||
|
||||
|
||||
Structure of entry
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
For values of primitive types (currently integers from 1 to 8 bytes long), entry holds one key-value pair. For string and blob types, entry holds part of the whole key-value pair. In case when a key-value pair spans multiple entries, all entries are stored in the same page.
|
||||
|
||||
@@ -200,7 +200,7 @@ Variable length values (strings and blobs) are written into subsequent entries,
|
||||
|
||||
|
||||
Namespaces
|
||||
~~~~~~~~~~
|
||||
^^^^^^^^^^
|
||||
|
||||
As mentioned above, each key-value pair belongs to one of the namespaces. Namespaces identifiers (strings) are stored as keys of key-value pairs in namespace with index 0. Values corresponding to these keys are indexes of these namespaces.
|
||||
|
||||
@@ -218,10 +218,9 @@ As mentioned above, each key-value pair belongs to one of the namespaces. Namesp
|
||||
|
||||
|
||||
Item hash list
|
||||
~~~~~~~~~~~~~~
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
To reduce the number of reads performed from flash memory, each member of Page class maintains a list of pairs: (item index; item hash). This list makes searches much quicker. Instead of iterating over all entries, reading them from flash one at a time, ``Page::findItem`` first performs search for item hash in the hash list. This gives the item index within the page, if such an item exists. Due to a hash collision it is possible that a different item will be found. This is handled by falling back to iteration over items in flash.
|
||||
|
||||
Each node in hash list contains a 24-bit hash and 8-bit item index. Hash is calculated based on item namespace and key name. CRC32 is used for calculation, result is truncated to 24 bits. To reduce overhead of storing 32-bit entries in a linked list, list is implemented as a doubly-linked list of arrays. Each array holds 29 entries, for the total size of 128 bytes, together with linked list pointers and 32-bit count field. Minimal amount of extra RAM useage per page is therefore 128 bytes, maximum is 640 bytes.
|
||||
|
||||
|
||||
|
@@ -28,23 +28,27 @@ extern "C" {
|
||||
*/
|
||||
typedef uint32_t nvs_handle;
|
||||
|
||||
#define ESP_ERR_NVS_BASE 0x1100
|
||||
#define ESP_ERR_NVS_NOT_INITIALIZED (ESP_ERR_NVS_BASE + 0x01)
|
||||
#define ESP_ERR_NVS_NOT_FOUND (ESP_ERR_NVS_BASE + 0x02)
|
||||
#define ESP_ERR_NVS_TYPE_MISMATCH (ESP_ERR_NVS_BASE + 0x03)
|
||||
#define ESP_ERR_NVS_READ_ONLY (ESP_ERR_NVS_BASE + 0x04)
|
||||
#define ESP_ERR_NVS_NOT_ENOUGH_SPACE (ESP_ERR_NVS_BASE + 0x05)
|
||||
#define ESP_ERR_NVS_INVALID_NAME (ESP_ERR_NVS_BASE + 0x06)
|
||||
#define ESP_ERR_NVS_INVALID_HANDLE (ESP_ERR_NVS_BASE + 0x07)
|
||||
#define ESP_ERR_NVS_REMOVE_FAILED (ESP_ERR_NVS_BASE + 0x08)
|
||||
#define ESP_ERR_NVS_KEY_TOO_LONG (ESP_ERR_NVS_BASE + 0x09)
|
||||
#define ESP_ERR_NVS_PAGE_FULL (ESP_ERR_NVS_BASE + 0x0a)
|
||||
#define ESP_ERR_NVS_INVALID_STATE (ESP_ERR_NVS_BASE + 0x0b)
|
||||
#define ESP_ERR_NVS_INVALID_LENGTH (ESP_ERR_NVS_BASE + 0x0c)
|
||||
#define ESP_ERR_NVS_BASE 0x1100 /*!< Starting number of error codes */
|
||||
#define ESP_ERR_NVS_NOT_INITIALIZED (ESP_ERR_NVS_BASE + 0x01) /*!< The storage driver is not initialized */
|
||||
#define ESP_ERR_NVS_NOT_FOUND (ESP_ERR_NVS_BASE + 0x02) /*!< Id namespace doesn’t exist yet and mode is NVS_READONLY */
|
||||
#define ESP_ERR_NVS_TYPE_MISMATCH (ESP_ERR_NVS_BASE + 0x03) /*!< TBA */
|
||||
#define ESP_ERR_NVS_READ_ONLY (ESP_ERR_NVS_BASE + 0x04) /*!< Storage handle was opened as read only */
|
||||
#define ESP_ERR_NVS_NOT_ENOUGH_SPACE (ESP_ERR_NVS_BASE + 0x05) /*!< There is not enough space in the underlying storage to save the value */
|
||||
#define ESP_ERR_NVS_INVALID_NAME (ESP_ERR_NVS_BASE + 0x06) /*!< Namespace name doesn’t satisfy constraints */
|
||||
#define ESP_ERR_NVS_INVALID_HANDLE (ESP_ERR_NVS_BASE + 0x07) /*!< Handle has been closed or is NULL */
|
||||
#define ESP_ERR_NVS_REMOVE_FAILED (ESP_ERR_NVS_BASE + 0x08) /*!< The value wasn’t updated because flash write operation has failed. The value was written however, and update will be finished after re-initialization of nvs, provided that flash operation doesn’t fail again. */
|
||||
#define ESP_ERR_NVS_KEY_TOO_LONG (ESP_ERR_NVS_BASE + 0x09) /*!< TBA */
|
||||
#define ESP_ERR_NVS_PAGE_FULL (ESP_ERR_NVS_BASE + 0x0a) /*!< TBA */
|
||||
#define ESP_ERR_NVS_INVALID_STATE (ESP_ERR_NVS_BASE + 0x0b) /*!< TBA */
|
||||
#define ESP_ERR_NVS_INVALID_LENGTH (ESP_ERR_NVS_BASE + 0x0c) /*!< TBA */
|
||||
|
||||
/**
|
||||
* @brief Mode of opening the non-volatile storage
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
NVS_READONLY,
|
||||
NVS_READWRITE
|
||||
NVS_READONLY, /*!< Read only */
|
||||
NVS_READWRITE /*!< Read and write */
|
||||
} nvs_open_mode;
|
||||
|
||||
/**
|
||||
@@ -63,7 +67,8 @@ typedef enum {
|
||||
* @param[out] out_handle If successful (return code is zero), handle will be
|
||||
* returned in this argument.
|
||||
*
|
||||
* @return - ESP_OK if storage handle was opened successfully
|
||||
* @return
|
||||
* - ESP_OK if storage handle was opened successfully
|
||||
* - ESP_ERR_NVS_NOT_INITIALIZED if the storage driver is not initialized
|
||||
* - ESP_ERR_NVS_NOT_FOUND id namespace doesn't exist yet and
|
||||
* mode is NVS_READONLY
|
||||
@@ -86,7 +91,8 @@ esp_err_t nvs_open(const char* name, nvs_open_mode open_mode, nvs_handle *out_ha
|
||||
* @param[in] value The value to set.
|
||||
* @param[in] length For nvs_set_blob: length of binary value to set, in bytes.
|
||||
*
|
||||
* @return - ESP_OK if value was set successfully
|
||||
* @return
|
||||
* - ESP_OK if value was set successfully
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_READ_ONLY if storage handle was opened as read only
|
||||
* - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints
|
||||
@@ -129,24 +135,26 @@ esp_err_t nvs_set_blob(nvs_handle handle, const char* key, const void* value, si
|
||||
* It is suggested that nvs_get/set_str is used for zero-terminated C strings, and
|
||||
* nvs_get/set_blob used for arbitrary data structures.
|
||||
*
|
||||
* Example of using nvs_get_i32:
|
||||
* \code{c}
|
||||
* // Example of using nvs_get_i32:
|
||||
* int32_t max_buffer_size = 4096; // default value
|
||||
* esp_err_t err = nvs_get_i32(my_handle, "max_buffer_size", &max_buffer_size);
|
||||
* assert(err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND);
|
||||
* // if ESP_ERR_NVS_NOT_FOUND was returned, max_buffer_size will still
|
||||
* // have its default value.
|
||||
*
|
||||
* Example (without error checking) of using nvs_get_str to get a string into dynamic array:
|
||||
* // Example (without error checking) of using nvs_get_str to get a string into dynamic array:
|
||||
* size_t required_size;
|
||||
* nvs_get_str(my_handle, "server_name", NULL, &required_size);
|
||||
* char* server_name = malloc(required_size);
|
||||
* nvs_get_str(my_handle, "server_name", server_name, &required_size);
|
||||
*
|
||||
* Example (without error checking) of using nvs_get_blob to get a binary data
|
||||
* // Example (without error checking) of using nvs_get_blob to get a binary data
|
||||
* into a static array:
|
||||
* uint8_t mac_addr[6];
|
||||
* size_t size = sizeof(mac_addr);
|
||||
* nvs_get_blob(my_handle, "dst_mac_addr", mac_addr, &size);
|
||||
* \endcode
|
||||
*
|
||||
* @param[in] handle Handle obtained from nvs_open function.
|
||||
* @param[in] key Key name. Maximal length is determined by the underlying
|
||||
@@ -162,7 +170,8 @@ esp_err_t nvs_set_blob(nvs_handle handle, const char* key, const void* value, si
|
||||
* zero, will be set to the actual length of the value
|
||||
* written. For nvs_get_str this includes zero terminator.
|
||||
*
|
||||
* @return - ESP_OK if the value was retrieved successfully
|
||||
* @return
|
||||
* - ESP_OK if the value was retrieved successfully
|
||||
* - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints
|
||||
@@ -191,7 +200,8 @@ esp_err_t nvs_get_blob(nvs_handle handle, const char* key, void* out_value, size
|
||||
* implementation, but is guaranteed to be at least
|
||||
* 16 characters. Shouldn't be empty.
|
||||
*
|
||||
* @return - ESP_OK if erase operation was successful
|
||||
* @return
|
||||
* - ESP_OK if erase operation was successful
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_READ_ONLY if handle was opened as read only
|
||||
* - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist
|
||||
@@ -207,7 +217,8 @@ esp_err_t nvs_erase_key(nvs_handle handle, const char* key);
|
||||
* @param[in] handle Storage handle obtained with nvs_open.
|
||||
* Handles that were opened read only cannot be used.
|
||||
*
|
||||
* @return - ESP_OK if erase operation was successful
|
||||
* @return
|
||||
* - ESP_OK if erase operation was successful
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_READ_ONLY if handle was opened as read only
|
||||
* - other error codes from the underlying storage driver
|
||||
@@ -224,7 +235,8 @@ esp_err_t nvs_erase_all(nvs_handle handle);
|
||||
* @param[in] handle Storage handle obtained with nvs_open.
|
||||
* Handles that were opened read only cannot be used.
|
||||
*
|
||||
* @return - ESP_OK if the changes have been written successfully
|
||||
* @return
|
||||
* - ESP_OK if the changes have been written successfully
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - other error codes from the underlying storage driver
|
||||
*/
|
||||
@@ -249,3 +261,4 @@ void nvs_close(nvs_handle handle);
|
||||
#endif
|
||||
|
||||
#endif //ESP_NVS_H
|
||||
|
||||
|
@@ -22,6 +22,8 @@ extern "C" {
|
||||
|
||||
Temporarily, this region is hardcoded as a 12KB (0x3000 byte)
|
||||
region starting at 24KB (0x6000 byte) offset in flash.
|
||||
|
||||
@return ESP_OK if flash was successfully initialised.
|
||||
*/
|
||||
esp_err_t nvs_flash_init(void);
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
// 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
|
||||
@@ -131,8 +131,12 @@ esp_err_t Page::writeEntryData(const uint8_t* data, size_t size)
|
||||
esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, const void* data, size_t dataSize)
|
||||
{
|
||||
Item item;
|
||||
|
||||
esp_err_t err;
|
||||
|
||||
if (mState == PageState::INVALID) {
|
||||
return ESP_ERR_NVS_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (mState == PageState::UNINITIALIZED) {
|
||||
err = initialize();
|
||||
if (err != ESP_OK) {
|
||||
@@ -166,7 +170,6 @@ esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, c
|
||||
}
|
||||
|
||||
// write first item
|
||||
|
||||
size_t span = (totalSize + ENTRY_SIZE - 1) / ENTRY_SIZE;
|
||||
item = Item(nsIndex, datatype, span, key);
|
||||
mHashList.insert(item, mNextFreeEntry);
|
||||
@@ -215,6 +218,11 @@ esp_err_t Page::readItem(uint8_t nsIndex, ItemType datatype, const char* key, vo
|
||||
{
|
||||
size_t index = 0;
|
||||
Item item;
|
||||
|
||||
if (mState == PageState::INVALID) {
|
||||
return ESP_ERR_NVS_INVALID_STATE;
|
||||
}
|
||||
|
||||
esp_err_t rc = findItem(nsIndex, datatype, key, index, item);
|
||||
if (rc != ESP_OK) {
|
||||
return rc;
|
||||
@@ -293,6 +301,8 @@ esp_err_t Page::eraseEntryAndSpan(size_t index)
|
||||
}
|
||||
if (item.calculateCrc32() != item.crc32) {
|
||||
rc = alterEntryState(index, EntryState::ERASED);
|
||||
--mUsedEntryCount;
|
||||
++mErasedEntryCount;
|
||||
if (rc != ESP_OK) {
|
||||
return rc;
|
||||
}
|
||||
@@ -465,7 +475,9 @@ esp_err_t Page::mLoadEntryTable()
|
||||
if (end > ENTRY_COUNT) {
|
||||
end = ENTRY_COUNT;
|
||||
}
|
||||
for (size_t i = 0; i < end; ++i) {
|
||||
size_t span;
|
||||
for (size_t i = 0; i < end; i += span) {
|
||||
span = 1;
|
||||
if (mEntryTable.get(i) == EntryState::ERASED) {
|
||||
lastItemIndex = INVALID_ENTRY;
|
||||
continue;
|
||||
@@ -479,6 +491,11 @@ esp_err_t Page::mLoadEntryTable()
|
||||
return err;
|
||||
}
|
||||
|
||||
mHashList.insert(item, i);
|
||||
|
||||
// search for potential duplicate item
|
||||
size_t duplicateIndex = mHashList.find(0, item);
|
||||
|
||||
if (item.crc32 != item.calculateCrc32()) {
|
||||
err = eraseEntryAndSpan(i);
|
||||
if (err != ESP_OK) {
|
||||
@@ -488,13 +505,9 @@ esp_err_t Page::mLoadEntryTable()
|
||||
continue;
|
||||
}
|
||||
|
||||
mHashList.insert(item, i);
|
||||
|
||||
if (item.datatype != ItemType::BLOB && item.datatype != ItemType::SZ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t span = item.span;
|
||||
if (item.datatype == ItemType::BLOB || item.datatype == ItemType::SZ) {
|
||||
span = item.span;
|
||||
bool needErase = false;
|
||||
for (size_t j = i; j < i + span; ++j) {
|
||||
if (mEntryTable.get(j) != EntryState::WRITTEN) {
|
||||
@@ -505,8 +518,13 @@ esp_err_t Page::mLoadEntryTable()
|
||||
}
|
||||
if (needErase) {
|
||||
eraseEntryAndSpan(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (duplicateIndex < i) {
|
||||
eraseEntryAndSpan(duplicateIndex);
|
||||
}
|
||||
i += span - 1;
|
||||
}
|
||||
|
||||
// check that last item is not duplicate
|
||||
@@ -785,8 +803,12 @@ void Page::debugDump() const
|
||||
Item item;
|
||||
readEntry(i, item);
|
||||
if (skip == 0) {
|
||||
printf("W ns=%2u type=%2u span=%3u key=\"%s\"\n", item.nsIndex, static_cast<unsigned>(item.datatype), item.span, item.key);
|
||||
printf("W ns=%2u type=%2u span=%3u key=\"%s\" len=%d\n", item.nsIndex, static_cast<unsigned>(item.datatype), item.span, item.key, (item.span != 1)?((int)item.varLength.dataSize):-1);
|
||||
if (item.span > 0 && item.span <= ENTRY_COUNT - i) {
|
||||
skip = item.span - 1;
|
||||
} else {
|
||||
skip = 0;
|
||||
}
|
||||
} else {
|
||||
printf("D\n");
|
||||
skip--;
|
||||
|
@@ -14,25 +14,51 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern "C" unsigned long crc32_le(unsigned long crc_in, unsigned char const* data, unsigned int length)
|
||||
{
|
||||
uint32_t i;
|
||||
bool bit;
|
||||
uint8_t c;
|
||||
uint32_t crc = (uint32_t) crc_in;
|
||||
static const unsigned int crc32_le_table[256] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
|
||||
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
|
||||
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
|
||||
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
|
||||
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
|
||||
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
|
||||
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
|
||||
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
|
||||
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
|
||||
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
|
||||
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
|
||||
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
|
||||
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
|
||||
|
||||
while (length--) {
|
||||
c = *data++;
|
||||
for (i = 0x80; i > 0; i >>= 1) {
|
||||
bit = crc & 0x80000000;
|
||||
if (c & i) {
|
||||
bit = !bit;
|
||||
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
|
||||
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
|
||||
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
|
||||
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
|
||||
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
|
||||
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
|
||||
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
|
||||
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
|
||||
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
|
||||
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
|
||||
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
|
||||
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
|
||||
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern "C" unsigned int crc32_le(unsigned int crc, unsigned char const * buf,unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
crc = ~crc;
|
||||
for(i=0;i<len;i++){
|
||||
crc = crc32_le_table[(crc^buf[i])&0xff]^(crc>>8);
|
||||
}
|
||||
crc <<= 1;
|
||||
if (bit) {
|
||||
crc ^= 0x04c11db7;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
|
@@ -74,11 +74,11 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size / 4; ++i) {
|
||||
if (mFailCountdown != SIZE_MAX && mFailCountdown-- == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size / 4; ++i) {
|
||||
uint32_t sv = src[i];
|
||||
size_t pos = dstAddr / 4 + i;
|
||||
uint32_t& dv = mData[pos];
|
||||
@@ -142,6 +142,18 @@ public:
|
||||
return reinterpret_cast<const uint8_t*>(mData.data());
|
||||
}
|
||||
|
||||
void load(const char* filename)
|
||||
{
|
||||
FILE* f = fopen(filename, "rb");
|
||||
fseek(f, 0, SEEK_END);
|
||||
off_t size = ftell(f);
|
||||
assert(size % SPI_FLASH_SEC_SIZE == 0);
|
||||
mData.resize(size);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
auto s = fread(mData.data(), SPI_FLASH_SEC_SIZE, size / SPI_FLASH_SEC_SIZE, f);
|
||||
assert(s == static_cast<size_t>(size / SPI_FLASH_SEC_SIZE));
|
||||
}
|
||||
|
||||
void clearStats()
|
||||
{
|
||||
mReadBytes = 0;
|
||||
|
@@ -894,7 +894,7 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey
|
||||
|
||||
size_t totalOps = 0;
|
||||
int lastPercent = -1;
|
||||
for (uint32_t errDelay = 4; ; ++errDelay) {
|
||||
for (uint32_t errDelay = 0; ; ++errDelay) {
|
||||
INFO(errDelay);
|
||||
emu.randomize(seed);
|
||||
emu.clearStats();
|
||||
@@ -903,23 +903,25 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey
|
||||
|
||||
if (totalOps != 0) {
|
||||
int percent = errDelay * 100 / totalOps;
|
||||
if (percent != lastPercent) {
|
||||
if (percent > lastPercent) {
|
||||
printf("%d/%d (%d%%)\r\n", errDelay, static_cast<int>(totalOps), percent);
|
||||
lastPercent = percent;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
|
||||
|
||||
nvs_handle handle;
|
||||
TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle));
|
||||
|
||||
size_t count = iter_count;
|
||||
|
||||
if (nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN) == ESP_OK) {
|
||||
if (nvs_open("namespace1", NVS_READWRITE, &handle) == ESP_OK) {
|
||||
if(test.doRandomThings(handle, gen, count) != ESP_ERR_FLASH_OP_FAIL) {
|
||||
nvs_close(handle);
|
||||
break;
|
||||
}
|
||||
nvs_close(handle);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ESP_OK(nvs_flash_init_custom(NVS_FLASH_SECTOR, NVS_FLASH_SECTOR_COUNT_MIN));
|
||||
TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle));
|
||||
@@ -929,7 +931,7 @@ TEST_CASE("test recovery from sudden poweroff", "[.][long][nvs][recovery][monkey
|
||||
CHECK(0);
|
||||
}
|
||||
nvs_close(handle);
|
||||
totalOps = emu.getEraseOps() + emu.getWriteOps();
|
||||
totalOps = emu.getEraseOps() + emu.getWriteBytes() / 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -951,6 +953,108 @@ TEST_CASE("test for memory leaks in open/set", "[leaks]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("duplicate items are removed", "[nvs][dupes]")
|
||||
{
|
||||
SpiFlashEmulator emu(3);
|
||||
{
|
||||
// create one item
|
||||
nvs::Page p;
|
||||
p.load(0);
|
||||
p.writeItem<uint8_t>(1, "opmode", 3);
|
||||
}
|
||||
{
|
||||
// add another two without deleting the first one
|
||||
nvs::Item item(1, ItemType::U8, 1, "opmode");
|
||||
item.data[0] = 2;
|
||||
item.crc32 = item.calculateCrc32();
|
||||
emu.write(3 * 32, reinterpret_cast<const uint32_t*>(&item), sizeof(item));
|
||||
emu.write(4 * 32, reinterpret_cast<const uint32_t*>(&item), sizeof(item));
|
||||
uint32_t mask = 0xFFFFFFEA;
|
||||
emu.write(32, &mask, 4);
|
||||
}
|
||||
{
|
||||
// load page and check that second item persists
|
||||
nvs::Storage s;
|
||||
s.init(0, 3);
|
||||
uint8_t val;
|
||||
ESP_ERROR_CHECK(s.readItem(1, "opmode", val));
|
||||
CHECK(val == 2);
|
||||
}
|
||||
{
|
||||
Page p;
|
||||
p.load(0);
|
||||
CHECK(p.getErasedEntryCount() == 2);
|
||||
CHECK(p.getUsedEntryCount() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("recovery after failure to write data", "[nvs]")
|
||||
{
|
||||
SpiFlashEmulator emu(3);
|
||||
const char str[] = "value 0123456789abcdef012345678value 0123456789abcdef012345678";
|
||||
|
||||
// make flash write fail exactly in Page::writeEntryData
|
||||
emu.failAfter(17);
|
||||
{
|
||||
Storage storage;
|
||||
TEST_ESP_OK(storage.init(0, 3));
|
||||
|
||||
TEST_ESP_ERR(storage.writeItem(1, ItemType::SZ, "key", str, strlen(str)), ESP_ERR_FLASH_OP_FAIL);
|
||||
|
||||
// check that repeated operations cause an error
|
||||
TEST_ESP_ERR(storage.writeItem(1, ItemType::SZ, "key", str, strlen(str)), ESP_ERR_NVS_INVALID_STATE);
|
||||
|
||||
uint8_t val;
|
||||
TEST_ESP_ERR(storage.readItem(1, ItemType::U8, "key", &val, sizeof(val)), ESP_ERR_NVS_NOT_FOUND);
|
||||
}
|
||||
{
|
||||
// load page and check that data was erased
|
||||
Page p;
|
||||
p.load(0);
|
||||
CHECK(p.getErasedEntryCount() == 3);
|
||||
CHECK(p.getUsedEntryCount() == 0);
|
||||
|
||||
// try to write again
|
||||
TEST_ESP_OK(p.writeItem(1, ItemType::SZ, "key", str, strlen(str)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("crc error in variable length item is handled", "[nvs]")
|
||||
{
|
||||
SpiFlashEmulator emu(3);
|
||||
const uint64_t before_val = 0xbef04e;
|
||||
const uint64_t after_val = 0xaf7e4;
|
||||
// write some data
|
||||
{
|
||||
Page p;
|
||||
p.load(0);
|
||||
TEST_ESP_OK(p.writeItem<uint64_t>(0, "before", before_val));
|
||||
const char* str = "foobar";
|
||||
TEST_ESP_OK(p.writeItem(0, ItemType::SZ, "key", str, strlen(str)));
|
||||
TEST_ESP_OK(p.writeItem<uint64_t>(0, "after", after_val));
|
||||
}
|
||||
// corrupt some data
|
||||
uint32_t w;
|
||||
CHECK(emu.read(&w, 32 * 3 + 8, sizeof(w)));
|
||||
w &= 0xf000000f;
|
||||
CHECK(emu.write(32 * 3 + 8, &w, sizeof(w)));
|
||||
// load and check
|
||||
{
|
||||
Page p;
|
||||
p.load(0);
|
||||
CHECK(p.getUsedEntryCount() == 2);
|
||||
CHECK(p.getErasedEntryCount() == 2);
|
||||
|
||||
uint64_t val;
|
||||
TEST_ESP_OK(p.readItem<uint64_t>(0, "before", val));
|
||||
CHECK(val == before_val);
|
||||
TEST_ESP_ERR(p.findItem(0, ItemType::SZ, "key"), ESP_ERR_NVS_NOT_FOUND);
|
||||
TEST_ESP_OK(p.readItem<uint64_t>(0, "after", val));
|
||||
CHECK(val == after_val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("dump all performance data", "[nvs]")
|
||||
{
|
||||
std::cout << "====================" << std::endl << "Dumping benchmarks" << std::endl;
|
||||
|
1797
components/openssl/OpenSSL-APIs.rst
Normal file
1797
components/openssl/OpenSSL-APIs.rst
Normal file
File diff suppressed because it is too large
Load Diff
10
components/openssl/component.mk
Normal file
10
components/openssl/component.mk
Normal file
@@ -0,0 +1,10 @@
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
COMPONENT_PRIV_INCLUDEDIRS := include/internal include/platform include/openssl
|
||||
|
||||
COMPONENT_SRCDIRS := library platform
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
44
components/openssl/include/internal/ssl3.h
Normal file
44
components/openssl/include/internal/ssl3.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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 _SSL3_H_
|
||||
#define _SSL3_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
# define SSL3_AD_CLOSE_NOTIFY 0
|
||||
# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */
|
||||
# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */
|
||||
# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */
|
||||
# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */
|
||||
# define SSL3_AD_NO_CERTIFICATE 41
|
||||
# define SSL3_AD_BAD_CERTIFICATE 42
|
||||
# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43
|
||||
# define SSL3_AD_CERTIFICATE_REVOKED 44
|
||||
# define SSL3_AD_CERTIFICATE_EXPIRED 45
|
||||
# define SSL3_AD_CERTIFICATE_UNKNOWN 46
|
||||
# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */
|
||||
|
||||
# define SSL3_AL_WARNING 1
|
||||
# define SSL3_AL_FATAL 2
|
||||
|
||||
#define SSL3_VERSION 0x0300
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
55
components/openssl/include/internal/ssl_cert.h
Normal file
55
components/openssl/include/internal/ssl_cert.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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_CERT_H_
|
||||
#define _SSL_CERT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ssl_types.h"
|
||||
|
||||
/**
|
||||
* @brief create a certification object include private key object according to input certification
|
||||
*
|
||||
* @param ic - input certification point
|
||||
*
|
||||
* @return certification object point
|
||||
*/
|
||||
CERT *__ssl_cert_new(CERT *ic);
|
||||
|
||||
/**
|
||||
* @brief create a certification object include private key object
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return certification object point
|
||||
*/
|
||||
CERT* ssl_cert_new(void);
|
||||
|
||||
/**
|
||||
* @brief free a certification object
|
||||
*
|
||||
* @param cert - certification object point
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void ssl_cert_free(CERT *cert);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
124
components/openssl/include/internal/ssl_code.h
Normal file
124
components/openssl/include/internal/ssl_code.h
Normal file
@@ -0,0 +1,124 @@
|
||||
// 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_CODE_H_
|
||||
#define _SSL_CODE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ssl3.h"
|
||||
#include "tls1.h"
|
||||
#include "x509_vfy.h"
|
||||
|
||||
/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
|
||||
# define SSL_SENT_SHUTDOWN 1
|
||||
# define SSL_RECEIVED_SHUTDOWN 2
|
||||
|
||||
# define SSL_VERIFY_NONE 0x00
|
||||
# define SSL_VERIFY_PEER 0x01
|
||||
# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
|
||||
# define SSL_VERIFY_CLIENT_ONCE 0x04
|
||||
|
||||
/*
|
||||
* The following 3 states are kept in ssl->rlayer.rstate when reads fail, you
|
||||
* should not need these
|
||||
*/
|
||||
# define SSL_ST_READ_HEADER 0xF0
|
||||
# define SSL_ST_READ_BODY 0xF1
|
||||
# define SSL_ST_READ_DONE 0xF2
|
||||
|
||||
# define SSL_NOTHING 1
|
||||
# define SSL_WRITING 2
|
||||
# define SSL_READING 3
|
||||
# define SSL_X509_LOOKUP 4
|
||||
# define SSL_ASYNC_PAUSED 5
|
||||
# define SSL_ASYNC_NO_JOBS 6
|
||||
|
||||
|
||||
# define SSL_ERROR_NONE 0
|
||||
# define SSL_ERROR_SSL 1
|
||||
# define SSL_ERROR_WANT_READ 2
|
||||
# define SSL_ERROR_WANT_WRITE 3
|
||||
# define SSL_ERROR_WANT_X509_LOOKUP 4
|
||||
# define SSL_ERROR_SYSCALL 5/* look at error stack/return value/errno */
|
||||
# define SSL_ERROR_ZERO_RETURN 6
|
||||
# define SSL_ERROR_WANT_CONNECT 7
|
||||
# define SSL_ERROR_WANT_ACCEPT 8
|
||||
# define SSL_ERROR_WANT_ASYNC 9
|
||||
# define SSL_ERROR_WANT_ASYNC_JOB 10
|
||||
|
||||
/* Message flow states */
|
||||
typedef enum {
|
||||
/* No handshake in progress */
|
||||
MSG_FLOW_UNINITED,
|
||||
/* A permanent error with this connection */
|
||||
MSG_FLOW_ERROR,
|
||||
/* We are about to renegotiate */
|
||||
MSG_FLOW_RENEGOTIATE,
|
||||
/* We are reading messages */
|
||||
MSG_FLOW_READING,
|
||||
/* We are writing messages */
|
||||
MSG_FLOW_WRITING,
|
||||
/* Handshake has finished */
|
||||
MSG_FLOW_FINISHED
|
||||
} MSG_FLOW_STATE;
|
||||
|
||||
/* SSL subsystem states */
|
||||
typedef enum {
|
||||
TLS_ST_BEFORE,
|
||||
TLS_ST_OK,
|
||||
DTLS_ST_CR_HELLO_VERIFY_REQUEST,
|
||||
TLS_ST_CR_SRVR_HELLO,
|
||||
TLS_ST_CR_CERT,
|
||||
TLS_ST_CR_CERT_STATUS,
|
||||
TLS_ST_CR_KEY_EXCH,
|
||||
TLS_ST_CR_CERT_REQ,
|
||||
TLS_ST_CR_SRVR_DONE,
|
||||
TLS_ST_CR_SESSION_TICKET,
|
||||
TLS_ST_CR_CHANGE,
|
||||
TLS_ST_CR_FINISHED,
|
||||
TLS_ST_CW_CLNT_HELLO,
|
||||
TLS_ST_CW_CERT,
|
||||
TLS_ST_CW_KEY_EXCH,
|
||||
TLS_ST_CW_CERT_VRFY,
|
||||
TLS_ST_CW_CHANGE,
|
||||
TLS_ST_CW_NEXT_PROTO,
|
||||
TLS_ST_CW_FINISHED,
|
||||
TLS_ST_SW_HELLO_REQ,
|
||||
TLS_ST_SR_CLNT_HELLO,
|
||||
DTLS_ST_SW_HELLO_VERIFY_REQUEST,
|
||||
TLS_ST_SW_SRVR_HELLO,
|
||||
TLS_ST_SW_CERT,
|
||||
TLS_ST_SW_KEY_EXCH,
|
||||
TLS_ST_SW_CERT_REQ,
|
||||
TLS_ST_SW_SRVR_DONE,
|
||||
TLS_ST_SR_CERT,
|
||||
TLS_ST_SR_KEY_EXCH,
|
||||
TLS_ST_SR_CERT_VRFY,
|
||||
TLS_ST_SR_NEXT_PROTO,
|
||||
TLS_ST_SR_CHANGE,
|
||||
TLS_ST_SR_FINISHED,
|
||||
TLS_ST_SW_SESSION_TICKET,
|
||||
TLS_ST_SW_CERT_STATUS,
|
||||
TLS_ST_SW_CHANGE,
|
||||
TLS_ST_SW_FINISHED
|
||||
} OSSL_HANDSHAKE_STATE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
92
components/openssl/include/internal/ssl_dbg.h
Normal file
92
components/openssl/include/internal/ssl_dbg.h
Normal file
@@ -0,0 +1,92 @@
|
||||
// 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_DEBUG_H_
|
||||
#define _SSL_DEBUG_H_
|
||||
|
||||
#include "platform/ssl_opt.h"
|
||||
#include "platform/ssl_port.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef SSL_DEBUG_ENBALE
|
||||
#define SSL_DEBUG_ENBALE 0
|
||||
#endif
|
||||
|
||||
#ifndef SSL_DEBUG_LEVEL
|
||||
#define SSL_DEBUG_LEVEL 0
|
||||
#endif
|
||||
|
||||
#ifndef SSL_ASSERT_ENABLE
|
||||
#define SSL_ASSERT_ENABLE 0
|
||||
#endif
|
||||
|
||||
#ifndef SSL_DEBUG_LOCATION_ENABLE
|
||||
#define SSL_DEBUG_LOCATION_ENABLE 0
|
||||
#endif
|
||||
|
||||
#if SSL_DEBUG_ENBALE
|
||||
#if !defined(SSL_PRINT_LOG) || !defined(SSL_ERROR_LOG) || !defined(SSL_LOCAL_LOG)
|
||||
#include "stdio.h"
|
||||
extern int printf(const char *fmt, ...);
|
||||
#ifndef SSL_PRINT_LOG
|
||||
#define SSL_PRINT_LOG printf
|
||||
#endif
|
||||
#ifndef SSL_ERROR_LOG
|
||||
#define SSL_ERROR_LOG printf
|
||||
#endif
|
||||
#ifndef SSL_LOCAL_LOG
|
||||
#define SSL_LOCAL_LOG printf
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#ifdef SSL_PRINT_LOG
|
||||
#undef SSL_PRINT_LOG
|
||||
#define SSL_PRINT_LOG(...)
|
||||
#endif
|
||||
#ifdef SSL_ERROR_LOG
|
||||
#undef SSL_ERROR_LOG
|
||||
#define SSL_ERROR_LOG(...)
|
||||
#endif
|
||||
#ifdef SSL_LOCAL_LOG
|
||||
#undef SSL_LOCAL_LOG
|
||||
#define SSL_LOCAL_LOG(...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SSL_DEBUG_LOCATION_ENABLE
|
||||
#define SSL_DEBUG_LOCATION() SSL_LOCAL_LOG("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__)
|
||||
#else
|
||||
#define SSL_DEBUG_LOCATION()
|
||||
#endif
|
||||
|
||||
#if SSL_ASSERT_ENABLE
|
||||
#define SSL_ASSERT(s) { if (!(s)) { SSL_DEBUG_LOCATION(); } }
|
||||
#else
|
||||
#define SSL_ASSERT(s)
|
||||
#endif
|
||||
|
||||
#define SSL_ERR(err, go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_ERROR_LOG(fmt, ##__VA_ARGS__); ret = err; goto go; }
|
||||
|
||||
#define SSL_RET(go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_ERROR_LOG(fmt, ##__VA_ARGS__); goto go; }
|
||||
|
||||
#define SSL_DEBUG(level, fmt, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT_LOG(fmt, ##__VA_ARGS__);} }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
28
components/openssl/include/internal/ssl_lib.h
Normal file
28
components/openssl/include/internal/ssl_lib.h
Normal file
@@ -0,0 +1,28 @@
|
||||
// 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_LIB_H_
|
||||
#define _SSL_LIB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ssl_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
121
components/openssl/include/internal/ssl_methods.h
Normal file
121
components/openssl/include/internal/ssl_methods.h
Normal file
@@ -0,0 +1,121 @@
|
||||
// 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_METHODS_H_
|
||||
#define _SSL_METHODS_H_
|
||||
|
||||
#include "ssl_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* TLS method function implement
|
||||
*/
|
||||
#define IMPLEMENT_TLS_METHOD_FUNC(func_name, \
|
||||
new, free, \
|
||||
handshake, shutdown, clear, \
|
||||
read, send, pending, \
|
||||
set_fd, get_fd, \
|
||||
set_bufflen, \
|
||||
get_verify_result, \
|
||||
get_state) \
|
||||
static const SSL_METHOD_FUNC func_name LOCAL_ATRR = { \
|
||||
new, \
|
||||
free, \
|
||||
handshake, \
|
||||
shutdown, \
|
||||
clear, \
|
||||
read, \
|
||||
send, \
|
||||
pending, \
|
||||
set_fd, \
|
||||
get_fd, \
|
||||
set_bufflen, \
|
||||
get_verify_result, \
|
||||
get_state \
|
||||
};
|
||||
|
||||
#define IMPLEMENT_TLS_METHOD(ver, mode, fun, func_name) \
|
||||
const SSL_METHOD* func_name(void) { \
|
||||
static const SSL_METHOD func_name##_data LOCAL_ATRR = { \
|
||||
ver, \
|
||||
mode, \
|
||||
&(fun), \
|
||||
}; \
|
||||
return &func_name##_data; \
|
||||
}
|
||||
|
||||
#define IMPLEMENT_SSL_METHOD(ver, mode, fun, func_name) \
|
||||
const SSL_METHOD* func_name(void) { \
|
||||
static const SSL_METHOD func_name##_data LOCAL_ATRR = { \
|
||||
ver, \
|
||||
mode, \
|
||||
&(fun), \
|
||||
}; \
|
||||
return &func_name##_data; \
|
||||
}
|
||||
|
||||
#define IMPLEMENT_X509_METHOD(func_name, \
|
||||
new, \
|
||||
free, \
|
||||
load, \
|
||||
show_info) \
|
||||
const X509_METHOD* func_name(void) { \
|
||||
static const X509_METHOD func_name##_data LOCAL_ATRR = { \
|
||||
new, \
|
||||
free, \
|
||||
load, \
|
||||
show_info \
|
||||
}; \
|
||||
return &func_name##_data; \
|
||||
}
|
||||
|
||||
#define IMPLEMENT_PKEY_METHOD(func_name, \
|
||||
new, \
|
||||
free, \
|
||||
load) \
|
||||
const PKEY_METHOD* func_name(void) { \
|
||||
static const PKEY_METHOD func_name##_data LOCAL_ATRR = { \
|
||||
new, \
|
||||
free, \
|
||||
load \
|
||||
}; \
|
||||
return &func_name##_data; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get X509 object method
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return X509 object method point
|
||||
*/
|
||||
const X509_METHOD* X509_method(void);
|
||||
|
||||
/**
|
||||
* @brief get private key object method
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return private key object method point
|
||||
*/
|
||||
const PKEY_METHOD* EVP_PKEY_method(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
86
components/openssl/include/internal/ssl_pkey.h
Normal file
86
components/openssl/include/internal/ssl_pkey.h
Normal file
@@ -0,0 +1,86 @@
|
||||
// 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_PKEY_H_
|
||||
#define _SSL_PKEY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ssl_types.h"
|
||||
|
||||
/**
|
||||
* @brief create a private key object according to input private key
|
||||
*
|
||||
* @param ipk - input private key point
|
||||
*
|
||||
* @return new private key object point
|
||||
*/
|
||||
EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk);
|
||||
|
||||
/**
|
||||
* @brief create a private key object
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return private key object point
|
||||
*/
|
||||
EVP_PKEY* EVP_PKEY_new(void);
|
||||
|
||||
/**
|
||||
* @brief load a character key context into system context. If '*a' is pointed to the
|
||||
* private key, then load key into it. Or create a new private key object
|
||||
*
|
||||
* @param type - private key type
|
||||
* @param a - a point pointed to a private key point
|
||||
* @param pp - a point pointed to the key context memory point
|
||||
* @param length - key bytes
|
||||
*
|
||||
* @return private key object point
|
||||
*/
|
||||
EVP_PKEY* d2i_PrivateKey(int type,
|
||||
EVP_PKEY **a,
|
||||
const unsigned char **pp,
|
||||
long length);
|
||||
|
||||
/**
|
||||
* @brief free a private key object
|
||||
*
|
||||
* @param pkey - private key object point
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void EVP_PKEY_free(EVP_PKEY *x);
|
||||
|
||||
/**
|
||||
* @brief load private key into the SSL
|
||||
*
|
||||
* @param type - private key type
|
||||
* @param ssl - SSL point
|
||||
* @param len - data bytes
|
||||
* @param d - data point
|
||||
*
|
||||
* @return result
|
||||
* 0 : failed
|
||||
* 1 : OK
|
||||
*/
|
||||
int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
52
components/openssl/include/internal/ssl_stack.h
Normal file
52
components/openssl/include/internal/ssl_stack.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef _SSL_STACK_H_
|
||||
#define _SSL_STACK_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ssl_types.h"
|
||||
|
||||
#define STACK_OF(type) struct stack_st_##type
|
||||
|
||||
#define SKM_DEFINE_STACK_OF(t1, t2, t3) \
|
||||
STACK_OF(t1); \
|
||||
static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \
|
||||
{ \
|
||||
return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \
|
||||
} \
|
||||
|
||||
#define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t)
|
||||
|
||||
/**
|
||||
* @brief create a openssl stack object
|
||||
*
|
||||
* @param c - stack function
|
||||
*
|
||||
* @return openssl stack object point
|
||||
*/
|
||||
OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c);
|
||||
|
||||
/**
|
||||
* @brief create a NULL function openssl stack object
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return openssl stack object point
|
||||
*/
|
||||
OPENSSL_STACK *OPENSSL_sk_new_null(void);
|
||||
|
||||
/**
|
||||
* @brief free openssl stack object
|
||||
*
|
||||
* @param openssl stack object point
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void OPENSSL_sk_free(OPENSSL_STACK *stack);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
288
components/openssl/include/internal/ssl_types.h
Normal file
288
components/openssl/include/internal/ssl_types.h
Normal file
@@ -0,0 +1,288 @@
|
||||
// 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_TYPES_H_
|
||||
#define _SSL_TYPES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ssl_code.h"
|
||||
|
||||
typedef void SSL_CIPHER;
|
||||
|
||||
typedef void X509_STORE_CTX;
|
||||
typedef void X509_STORE;
|
||||
|
||||
typedef void RSA;
|
||||
|
||||
typedef void STACK;
|
||||
typedef void BIO;
|
||||
|
||||
#define ossl_inline inline
|
||||
|
||||
#define SSL_METHOD_CALL(f, s, ...) s->method->func->ssl_##f(s, ##__VA_ARGS__)
|
||||
#define X509_METHOD_CALL(f, x, ...) x->method->x509_##f(x, ##__VA_ARGS__)
|
||||
#define EVP_PKEY_METHOD_CALL(f, k, ...) k->method->pkey_##f(k, ##__VA_ARGS__)
|
||||
|
||||
typedef int (*OPENSSL_sk_compfunc)(const void *, const void *);
|
||||
|
||||
struct stack_st;
|
||||
typedef struct stack_st OPENSSL_STACK;
|
||||
|
||||
struct ssl_method_st;
|
||||
typedef struct ssl_method_st SSL_METHOD;
|
||||
|
||||
struct ssl_method_func_st;
|
||||
typedef struct ssl_method_func_st SSL_METHOD_FUNC;
|
||||
|
||||
struct record_layer_st;
|
||||
typedef struct record_layer_st RECORD_LAYER;
|
||||
|
||||
struct ossl_statem_st;
|
||||
typedef struct ossl_statem_st OSSL_STATEM;
|
||||
|
||||
struct ssl_session_st;
|
||||
typedef struct ssl_session_st SSL_SESSION;
|
||||
|
||||
struct ssl_ctx_st;
|
||||
typedef struct ssl_ctx_st SSL_CTX;
|
||||
|
||||
struct ssl_st;
|
||||
typedef struct ssl_st SSL;
|
||||
|
||||
struct cert_st;
|
||||
typedef struct cert_st CERT;
|
||||
|
||||
struct x509_st;
|
||||
typedef struct x509_st X509;
|
||||
|
||||
struct X509_VERIFY_PARAM_st;
|
||||
typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM;
|
||||
|
||||
struct evp_pkey_st;
|
||||
typedef struct evp_pkey_st EVP_PKEY;
|
||||
|
||||
struct x509_method_st;
|
||||
typedef struct x509_method_st X509_METHOD;
|
||||
|
||||
struct pkey_method_st;
|
||||
typedef struct pkey_method_st PKEY_METHOD;
|
||||
|
||||
struct stack_st {
|
||||
|
||||
char **data;
|
||||
|
||||
int num_alloc;
|
||||
|
||||
OPENSSL_sk_compfunc c;
|
||||
};
|
||||
|
||||
struct evp_pkey_st {
|
||||
|
||||
void *pkey_pm;
|
||||
|
||||
const PKEY_METHOD *method;
|
||||
};
|
||||
|
||||
struct x509_st {
|
||||
|
||||
/* X509 certification platform private point */
|
||||
void *x509_pm;
|
||||
|
||||
const X509_METHOD *method;
|
||||
};
|
||||
|
||||
struct cert_st {
|
||||
|
||||
int sec_level;
|
||||
|
||||
X509 *x509;
|
||||
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
};
|
||||
|
||||
struct ossl_statem_st {
|
||||
|
||||
MSG_FLOW_STATE state;
|
||||
|
||||
int hand_state;
|
||||
};
|
||||
|
||||
struct record_layer_st {
|
||||
|
||||
int rstate;
|
||||
|
||||
int read_ahead;
|
||||
};
|
||||
|
||||
struct ssl_session_st {
|
||||
|
||||
long timeout;
|
||||
|
||||
long time;
|
||||
|
||||
X509 *peer;
|
||||
};
|
||||
|
||||
struct X509_VERIFY_PARAM_st {
|
||||
|
||||
int depth;
|
||||
|
||||
};
|
||||
|
||||
struct ssl_ctx_st
|
||||
{
|
||||
int version;
|
||||
|
||||
int references;
|
||||
|
||||
unsigned long options;
|
||||
|
||||
#if 0
|
||||
struct alpn_protocols alpn_protocol;
|
||||
#endif
|
||||
|
||||
const SSL_METHOD *method;
|
||||
|
||||
CERT *cert;
|
||||
|
||||
X509 *client_CA;
|
||||
|
||||
int verify_mode;
|
||||
|
||||
int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx);
|
||||
|
||||
long session_timeout;
|
||||
|
||||
int read_ahead;
|
||||
|
||||
int read_buffer_len;
|
||||
|
||||
X509_VERIFY_PARAM param;
|
||||
};
|
||||
|
||||
struct ssl_st
|
||||
{
|
||||
/* protocol version(one of SSL3.0, TLS1.0, etc.) */
|
||||
int version;
|
||||
|
||||
unsigned long options;
|
||||
|
||||
/* shut things down(0x01 : sent, 0x02 : received) */
|
||||
int shutdown;
|
||||
|
||||
CERT *cert;
|
||||
|
||||
X509 *client_CA;
|
||||
|
||||
SSL_CTX *ctx;
|
||||
|
||||
const SSL_METHOD *method;
|
||||
|
||||
RECORD_LAYER rlayer;
|
||||
|
||||
/* where we are */
|
||||
OSSL_STATEM statem;
|
||||
|
||||
SSL_SESSION *session;
|
||||
|
||||
int verify_mode;
|
||||
|
||||
int (*verify_callback) (int ok, X509_STORE_CTX *ctx);
|
||||
|
||||
int rwstate;
|
||||
|
||||
long verify_result;
|
||||
|
||||
X509_VERIFY_PARAM param;
|
||||
|
||||
int err;
|
||||
|
||||
void (*info_callback) (const SSL *ssl, int type, int val);
|
||||
|
||||
/* SSL low-level system arch point */
|
||||
void *ssl_pm;
|
||||
};
|
||||
|
||||
struct ssl_method_st {
|
||||
/* protocol version(one of SSL3.0, TLS1.0, etc.) */
|
||||
int version;
|
||||
|
||||
/* SSL mode(client(0) , server(1), not known(-1)) */
|
||||
int endpoint;
|
||||
|
||||
const SSL_METHOD_FUNC *func;
|
||||
};
|
||||
|
||||
struct ssl_method_func_st {
|
||||
|
||||
int (*ssl_new)(SSL *ssl);
|
||||
|
||||
void (*ssl_free)(SSL *ssl);
|
||||
|
||||
int (*ssl_handshake)(SSL *ssl);
|
||||
|
||||
int (*ssl_shutdown)(SSL *ssl);
|
||||
|
||||
int (*ssl_clear)(SSL *ssl);
|
||||
|
||||
int (*ssl_read)(SSL *ssl, void *buffer, int len);
|
||||
|
||||
int (*ssl_send)(SSL *ssl, const void *buffer, int len);
|
||||
|
||||
int (*ssl_pending)(const SSL *ssl);
|
||||
|
||||
void (*ssl_set_fd)(SSL *ssl, int fd, int mode);
|
||||
|
||||
int (*ssl_get_fd)(const SSL *ssl, int mode);
|
||||
|
||||
void (*ssl_set_bufflen)(SSL *ssl, int len);
|
||||
|
||||
long (*ssl_get_verify_result)(const SSL *ssl);
|
||||
|
||||
OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl);
|
||||
};
|
||||
|
||||
struct x509_method_st {
|
||||
|
||||
int (*x509_new)(X509 *x, X509 *m_x);
|
||||
|
||||
void (*x509_free)(X509 *x);
|
||||
|
||||
int (*x509_load)(X509 *x, const unsigned char *buf, int len);
|
||||
|
||||
int (*x509_show_info)(X509 *x);
|
||||
};
|
||||
|
||||
struct pkey_method_st {
|
||||
|
||||
int (*pkey_new)(EVP_PKEY *pkey, EVP_PKEY *m_pkey);
|
||||
|
||||
void (*pkey_free)(EVP_PKEY *pkey);
|
||||
|
||||
int (*pkey_load)(EVP_PKEY *pkey, const unsigned char *buf, int len);
|
||||
};
|
||||
|
||||
typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out,
|
||||
unsigned char *outlen, const unsigned char *in,
|
||||
unsigned int inlen, void *arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
108
components/openssl/include/internal/ssl_x509.h
Normal file
108
components/openssl/include/internal/ssl_x509.h
Normal file
@@ -0,0 +1,108 @@
|
||||
// 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_X509_H_
|
||||
#define _SSL_X509_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ssl_types.h"
|
||||
#include "ssl_stack.h"
|
||||
|
||||
DEFINE_STACK_OF(X509_NAME)
|
||||
|
||||
/**
|
||||
* @brief create a X509 certification object according to input X509 certification
|
||||
*
|
||||
* @param ix - input X509 certification point
|
||||
*
|
||||
* @return new X509 certification object point
|
||||
*/
|
||||
X509* __X509_new(X509 *ix);
|
||||
|
||||
/**
|
||||
* @brief create a X509 certification object
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return X509 certification object point
|
||||
*/
|
||||
X509* X509_new(void);
|
||||
|
||||
/**
|
||||
* @brief load a character certification context into system context. If '*cert' is pointed to the
|
||||
* certification, then load certification into it. Or create a new X509 certification object
|
||||
*
|
||||
* @param cert - a point pointed to X509 certification
|
||||
* @param buffer - a point pointed to the certification context memory point
|
||||
* @param length - certification bytes
|
||||
*
|
||||
* @return X509 certification object point
|
||||
*/
|
||||
X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len);
|
||||
|
||||
/**
|
||||
* @brief free a X509 certification object
|
||||
*
|
||||
* @param x - X509 certification object point
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void X509_free(X509 *x);
|
||||
|
||||
/**
|
||||
* @brief set SSL context client CA certification
|
||||
*
|
||||
* @param ctx - SSL context point
|
||||
* @param x - X509 certification point
|
||||
*
|
||||
* @return result
|
||||
* 0 : failed
|
||||
* 1 : OK
|
||||
*/
|
||||
int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
|
||||
|
||||
/**
|
||||
* @brief add CA client certification into the SSL
|
||||
*
|
||||
* @param ssl - SSL point
|
||||
* @param x - X509 certification point
|
||||
*
|
||||
* @return result
|
||||
* 0 : failed
|
||||
* 1 : OK
|
||||
*/
|
||||
int SSL_add_client_CA(SSL *ssl, X509 *x);
|
||||
|
||||
/**
|
||||
* @brief load certification into the SSL
|
||||
*
|
||||
* @param ssl - SSL point
|
||||
* @param len - data bytes
|
||||
* @param d - data point
|
||||
*
|
||||
* @return result
|
||||
* 0 : failed
|
||||
* 1 : OK
|
||||
*
|
||||
*/
|
||||
int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
55
components/openssl/include/internal/tls1.h
Normal file
55
components/openssl/include/internal/tls1.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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 _TLS1_H_
|
||||
#define _TLS1_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
# define TLS1_AD_DECRYPTION_FAILED 21
|
||||
# define TLS1_AD_RECORD_OVERFLOW 22
|
||||
# define TLS1_AD_UNKNOWN_CA 48/* fatal */
|
||||
# define TLS1_AD_ACCESS_DENIED 49/* fatal */
|
||||
# define TLS1_AD_DECODE_ERROR 50/* fatal */
|
||||
# define TLS1_AD_DECRYPT_ERROR 51
|
||||
# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */
|
||||
# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */
|
||||
# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */
|
||||
# define TLS1_AD_INTERNAL_ERROR 80/* fatal */
|
||||
# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */
|
||||
# define TLS1_AD_USER_CANCELLED 90
|
||||
# define TLS1_AD_NO_RENEGOTIATION 100
|
||||
/* codes 110-114 are from RFC3546 */
|
||||
# define TLS1_AD_UNSUPPORTED_EXTENSION 110
|
||||
# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111
|
||||
# define TLS1_AD_UNRECOGNIZED_NAME 112
|
||||
# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
|
||||
# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
|
||||
# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */
|
||||
# define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */
|
||||
|
||||
/* Special value for method supporting multiple versions */
|
||||
#define TLS_ANY_VERSION 0x10000
|
||||
|
||||
#define TLS1_VERSION 0x0301
|
||||
#define TLS1_1_VERSION 0x0302
|
||||
#define TLS1_2_VERSION 0x0303
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
111
components/openssl/include/internal/x509_vfy.h
Normal file
111
components/openssl/include/internal/x509_vfy.h
Normal file
@@ -0,0 +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
|
1737
components/openssl/include/openssl/ssl.h
Normal file
1737
components/openssl/include/openssl/ssl.h
Normal file
File diff suppressed because it is too large
Load Diff
48
components/openssl/include/platform/ssl_opt.h
Normal file
48
components/openssl/include/platform/ssl_opt.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// 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_OPT_H_
|
||||
#define _SSL_OPT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* if not define "ESP32_IDF_PLATFORM", system will use esp8266 platform interface
|
||||
*/
|
||||
#define ESP32_IDF_PLATFORM
|
||||
|
||||
/**
|
||||
* openssl debug print function enable
|
||||
*/
|
||||
#define SSL_DEBUG_ENBALE 0
|
||||
|
||||
/**
|
||||
* openssl debug print function level. function whose level is lower that "SSL_DEBUG_LEVEL"
|
||||
* will not print message
|
||||
*/
|
||||
#define SSL_DEBUG_LEVEL 0
|
||||
|
||||
/**
|
||||
* openssl assert function enable, it will check the input paramter and print the message
|
||||
*/
|
||||
#define SSL_ASSERT_ENABLE 0
|
||||
|
||||
/**
|
||||
* openssl location function enable, it will print location of the positioning error
|
||||
*/
|
||||
#define SSL_DEBUG_LOCATION_ENABLE 0
|
||||
|
||||
#endif
|
56
components/openssl/include/platform/ssl_pm.h
Normal file
56
components/openssl/include/platform/ssl_pm.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// 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_PM_H_
|
||||
#define _SSL_PM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ssl_types.h"
|
||||
#include "ssl_port.h"
|
||||
|
||||
#define LOCAL_ATRR
|
||||
|
||||
int ssl_pm_new(SSL *ssl);
|
||||
void ssl_pm_free(SSL *ssl);
|
||||
|
||||
int ssl_pm_handshake(SSL *ssl);
|
||||
int ssl_pm_shutdown(SSL *ssl);
|
||||
int ssl_pm_clear(SSL *ssl);
|
||||
|
||||
int ssl_pm_read(SSL *ssl, void *buffer, int len);
|
||||
int ssl_pm_send(SSL *ssl, const void *buffer, int len);
|
||||
int ssl_pm_pending(const SSL *ssl);
|
||||
|
||||
void ssl_pm_set_fd(SSL *ssl, int fd, int mode);
|
||||
int ssl_pm_get_fd(const SSL *ssl, int mode);
|
||||
|
||||
OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl);
|
||||
|
||||
void ssl_pm_set_bufflen(SSL *ssl, int len);
|
||||
|
||||
int x509_pm_show_info(X509 *x);
|
||||
int x509_pm_new(X509 *x, X509 *m_x);
|
||||
void x509_pm_free(X509 *x);
|
||||
int x509_pm_load(X509 *x, const unsigned char *buffer, int len);
|
||||
|
||||
int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pk);
|
||||
void pkey_pm_free(EVP_PKEY *pk);
|
||||
int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len);
|
||||
|
||||
long ssl_pm_get_verify_result(const SSL *ssl);
|
||||
|
||||
#endif
|
49
components/openssl/include/platform/ssl_port.h
Normal file
49
components/openssl/include/platform/ssl_port.h
Normal file
@@ -0,0 +1,49 @@
|
||||
// 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_PORT_H_
|
||||
#define _SSL_PORT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform/ssl_opt.h"
|
||||
|
||||
#ifdef ESP32_IDF_PLATFORM
|
||||
|
||||
#include "esp_types.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
void *ssl_mem_zalloc(size_t size);
|
||||
void *ssl_mem_malloc(size_t size);
|
||||
void ssl_mem_free(void *p);
|
||||
|
||||
void* ssl_memcpy(void *to, const void *from, size_t size);
|
||||
size_t ssl_strlen(const char *src);
|
||||
|
||||
void ssl_speed_up_enter(void);
|
||||
void ssl_speed_up_exit(void);
|
||||
|
||||
#define SSL_PRINT_LOG(fmt, ...) ESP_LOGD("openssl", fmt, ##__VA_ARGS__)
|
||||
#define SSL_ERROR_LOG(fmt, ...) ESP_LOGE("openssl", fmt, ##__VA_ARGS__)
|
||||
#define SSL_LOCAL_LOG(fmt, ...) ESP_LOGD("openssl", fmt, ##__VA_ARGS__)
|
||||
|
||||
#elif defined(SSL_PLATFORM_USER_INCLUDE)
|
||||
|
||||
SSL_PLATFORM_USER_INCLUDE
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
79
components/openssl/library/ssl_cert.c
Normal file
79
components/openssl/library/ssl_cert.c
Normal file
@@ -0,0 +1,79 @@
|
||||
// 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.
|
||||
|
||||
#include "ssl_cert.h"
|
||||
#include "ssl_pkey.h"
|
||||
#include "ssl_x509.h"
|
||||
#include "ssl_dbg.h"
|
||||
#include "ssl_port.h"
|
||||
|
||||
/**
|
||||
* @brief create a certification object according to input certification
|
||||
*/
|
||||
CERT *__ssl_cert_new(CERT *ic)
|
||||
{
|
||||
CERT *cert;
|
||||
|
||||
X509 *ix;
|
||||
EVP_PKEY *ipk;
|
||||
|
||||
cert = ssl_mem_zalloc(sizeof(CERT));
|
||||
if (!cert)
|
||||
SSL_RET(failed1, "ssl_mem_zalloc\n");
|
||||
|
||||
if (ic) {
|
||||
ipk = ic->pkey;
|
||||
ix = ic->x509;
|
||||
} else {
|
||||
ipk = NULL;
|
||||
ix = NULL;
|
||||
}
|
||||
|
||||
cert->pkey = __EVP_PKEY_new(ipk);
|
||||
if (!cert->pkey)
|
||||
SSL_RET(failed2, "__EVP_PKEY_new\n");
|
||||
|
||||
cert->x509 = __X509_new(ix);
|
||||
if (!cert->x509)
|
||||
SSL_RET(failed3, "__X509_new\n");
|
||||
|
||||
return cert;
|
||||
|
||||
failed3:
|
||||
EVP_PKEY_free(cert->pkey);
|
||||
failed2:
|
||||
ssl_mem_free(cert);
|
||||
failed1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief create a certification object include private key object
|
||||
*/
|
||||
CERT *ssl_cert_new(void)
|
||||
{
|
||||
return __ssl_cert_new(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief free a certification object
|
||||
*/
|
||||
void ssl_cert_free(CERT *cert)
|
||||
{
|
||||
X509_free(cert->x509);
|
||||
|
||||
EVP_PKEY_free(cert->pkey);
|
||||
|
||||
ssl_mem_free(cert);
|
||||
}
|
1506
components/openssl/library/ssl_lib.c
Normal file
1506
components/openssl/library/ssl_lib.c
Normal file
File diff suppressed because it is too large
Load Diff
81
components/openssl/library/ssl_methods.c
Normal file
81
components/openssl/library/ssl_methods.c
Normal file
@@ -0,0 +1,81 @@
|
||||
// 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.
|
||||
|
||||
#include "ssl_methods.h"
|
||||
#include "ssl_pm.h"
|
||||
|
||||
/**
|
||||
* TLS method function collection
|
||||
*/
|
||||
IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func,
|
||||
ssl_pm_new, ssl_pm_free,
|
||||
ssl_pm_handshake, ssl_pm_shutdown, ssl_pm_clear,
|
||||
ssl_pm_read, ssl_pm_send, ssl_pm_pending,
|
||||
ssl_pm_set_fd, ssl_pm_get_fd,
|
||||
ssl_pm_set_bufflen,
|
||||
ssl_pm_get_verify_result,
|
||||
ssl_pm_get_state);
|
||||
|
||||
/**
|
||||
* TLS or SSL client method collection
|
||||
*/
|
||||
IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 0, TLS_method_func, TLS_client_method);
|
||||
|
||||
IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 0, TLS_method_func, TLSv1_2_client_method);
|
||||
|
||||
IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 0, TLS_method_func, TLSv1_1_client_method);
|
||||
|
||||
IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_client_method);
|
||||
|
||||
IMPLEMENT_SSL_METHOD(SSL3_VERSION, 0, TLS_method_func, SSLv3_client_method);
|
||||
|
||||
/**
|
||||
* TLS or SSL server method collection
|
||||
*/
|
||||
IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 1, TLS_method_func, TLS_server_method);
|
||||
|
||||
IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 1, TLS_method_func, TLSv1_1_server_method);
|
||||
|
||||
IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 1, TLS_method_func, TLSv1_2_server_method);
|
||||
|
||||
IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_server_method);
|
||||
|
||||
IMPLEMENT_SSL_METHOD(SSL3_VERSION, 1, TLS_method_func, SSLv3_server_method);
|
||||
|
||||
/**
|
||||
* TLS or SSL method collection
|
||||
*/
|
||||
IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, -1, TLS_method_func, TLS_method);
|
||||
|
||||
IMPLEMENT_SSL_METHOD(TLS1_2_VERSION, -1, TLS_method_func, TLSv1_2_method);
|
||||
|
||||
IMPLEMENT_SSL_METHOD(TLS1_1_VERSION, -1, TLS_method_func, TLSv1_1_method);
|
||||
|
||||
IMPLEMENT_SSL_METHOD(TLS1_VERSION, -1, TLS_method_func, TLSv1_method);
|
||||
|
||||
IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method);
|
||||
|
||||
/**
|
||||
* @brief get X509 object method
|
||||
*/
|
||||
IMPLEMENT_X509_METHOD(X509_method,
|
||||
x509_pm_new, x509_pm_free,
|
||||
x509_pm_load, x509_pm_show_info);
|
||||
|
||||
/**
|
||||
* @brief get private key object method
|
||||
*/
|
||||
IMPLEMENT_PKEY_METHOD(EVP_PKEY_method,
|
||||
pkey_pm_new, pkey_pm_free,
|
||||
pkey_pm_load);
|
220
components/openssl/library/ssl_pkey.c
Normal file
220
components/openssl/library/ssl_pkey.c
Normal file
@@ -0,0 +1,220 @@
|
||||
// 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.
|
||||
|
||||
#include "ssl_pkey.h"
|
||||
#include "ssl_methods.h"
|
||||
#include "ssl_dbg.h"
|
||||
#include "ssl_port.h"
|
||||
|
||||
/**
|
||||
* @brief create a private key object according to input private key
|
||||
*/
|
||||
EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk)
|
||||
{
|
||||
int ret;
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
pkey = ssl_mem_zalloc(sizeof(EVP_PKEY));
|
||||
if (!pkey)
|
||||
SSL_RET(failed1, "ssl_mem_zalloc\n");
|
||||
|
||||
if (ipk) {
|
||||
pkey->method = ipk->method;
|
||||
} else {
|
||||
pkey->method = EVP_PKEY_method();
|
||||
}
|
||||
|
||||
ret = EVP_PKEY_METHOD_CALL(new, pkey, ipk);
|
||||
if (ret)
|
||||
SSL_RET(failed2, "EVP_PKEY_METHOD_CALL\n");
|
||||
|
||||
return pkey;
|
||||
|
||||
failed2:
|
||||
ssl_mem_free(pkey);
|
||||
failed1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief create a private key object
|
||||
*/
|
||||
EVP_PKEY* EVP_PKEY_new(void)
|
||||
{
|
||||
return __EVP_PKEY_new(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief free a private key object
|
||||
*/
|
||||
void EVP_PKEY_free(EVP_PKEY *pkey)
|
||||
{
|
||||
EVP_PKEY_METHOD_CALL(free, pkey);
|
||||
|
||||
ssl_mem_free(pkey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load a character key context into system context. If '*a' is pointed to the
|
||||
* private key, then load key into it. Or create a new private key object
|
||||
*/
|
||||
EVP_PKEY *d2i_PrivateKey(int type,
|
||||
EVP_PKEY **a,
|
||||
const unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
int m = 0;
|
||||
int ret;
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
SSL_ASSERT(pp);
|
||||
SSL_ASSERT(*pp);
|
||||
SSL_ASSERT(length);
|
||||
|
||||
if (a && *a) {
|
||||
pkey = *a;
|
||||
} else {
|
||||
pkey = EVP_PKEY_new();;
|
||||
if (!pkey)
|
||||
SSL_RET(failed1, "EVP_PKEY_new\n");
|
||||
m = 1;
|
||||
}
|
||||
|
||||
ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, length);
|
||||
if (ret)
|
||||
SSL_RET(failed2, "EVP_PKEY_METHOD_CALL\n");
|
||||
|
||||
if (a)
|
||||
*a = pkey;
|
||||
|
||||
return pkey;
|
||||
|
||||
failed2:
|
||||
if (m)
|
||||
EVP_PKEY_free(pkey);
|
||||
failed1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the SSL context private key
|
||||
*/
|
||||
int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
SSL_ASSERT(ctx);
|
||||
SSL_ASSERT(pkey);
|
||||
|
||||
if (ctx->cert->pkey == pkey)
|
||||
return 1;
|
||||
|
||||
if (ctx->cert->pkey)
|
||||
EVP_PKEY_free(ctx->cert->pkey);
|
||||
|
||||
ctx->cert->pkey = pkey;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the SSL private key
|
||||
*/
|
||||
int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
|
||||
{
|
||||
SSL_ASSERT(ssl);
|
||||
SSL_ASSERT(pkey);
|
||||
|
||||
if (ssl->cert->pkey == pkey)
|
||||
return 1;
|
||||
|
||||
if (ssl->cert->pkey)
|
||||
EVP_PKEY_free(ssl->cert->pkey);
|
||||
|
||||
ssl->cert->pkey = pkey;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load private key into the SSL context
|
||||
*/
|
||||
int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
|
||||
const unsigned char *d, long len)
|
||||
{
|
||||
int ret;
|
||||
EVP_PKEY *pk;
|
||||
|
||||
pk = d2i_PrivateKey(0, NULL, &d, len);
|
||||
if (!pk)
|
||||
SSL_RET(failed1, "d2i_PrivateKey\n");
|
||||
|
||||
ret = SSL_CTX_use_PrivateKey(ctx, pk);
|
||||
if (!ret)
|
||||
SSL_RET(failed2, "SSL_CTX_use_PrivateKey\n");
|
||||
|
||||
return 1;
|
||||
|
||||
failed2:
|
||||
EVP_PKEY_free(pk);
|
||||
failed1:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load private key into the SSL
|
||||
*/
|
||||
int SSL_use_PrivateKey_ASN1(int type, SSL *ssl,
|
||||
const unsigned char *d, long len)
|
||||
{
|
||||
int ret;
|
||||
EVP_PKEY *pk;
|
||||
|
||||
pk = d2i_PrivateKey(0, NULL, &d, len);
|
||||
if (!pk)
|
||||
SSL_RET(failed1, "d2i_PrivateKey\n");
|
||||
|
||||
ret = SSL_use_PrivateKey(ssl, pk);
|
||||
if (!ret)
|
||||
SSL_RET(failed2, "SSL_use_PrivateKey\n");
|
||||
|
||||
return 1;
|
||||
|
||||
failed2:
|
||||
EVP_PKEY_free(pk);
|
||||
failed1:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load the private key file into SSL context
|
||||
*/
|
||||
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load the private key file into SSL
|
||||
*/
|
||||
int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load the RSA ASN1 private key into SSL context
|
||||
*/
|
||||
int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
|
||||
{
|
||||
return SSL_CTX_use_PrivateKey_ASN1(0, ctx, d, len);
|
||||
}
|
70
components/openssl/library/ssl_stack.c
Normal file
70
components/openssl/library/ssl_stack.c
Normal file
@@ -0,0 +1,70 @@
|
||||
// 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.
|
||||
|
||||
#include "ssl_stack.h"
|
||||
#include "ssl_dbg.h"
|
||||
#include "ssl_port.h"
|
||||
|
||||
#ifndef CONFIG_MIN_NODES
|
||||
#define MIN_NODES 4
|
||||
#else
|
||||
#define MIN_NODES CONFIG_MIN_NODES
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief create a openssl stack object
|
||||
*/
|
||||
OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c)
|
||||
{
|
||||
OPENSSL_STACK *stack;
|
||||
char **data;
|
||||
|
||||
stack = ssl_mem_zalloc(sizeof(OPENSSL_STACK));
|
||||
if (!stack)
|
||||
SSL_RET(failed1, "ssl_mem_zalloc\n");
|
||||
|
||||
data = ssl_mem_zalloc(sizeof(*data) * MIN_NODES);
|
||||
if (!data)
|
||||
SSL_RET(failed2, "ssl_mem_zalloc\n");
|
||||
|
||||
stack->data = data;
|
||||
stack->num_alloc = MIN_NODES;
|
||||
stack->c = c;
|
||||
|
||||
return stack;
|
||||
|
||||
failed2:
|
||||
ssl_mem_free(stack);
|
||||
failed1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief create a NULL function openssl stack object
|
||||
*/
|
||||
OPENSSL_STACK *OPENSSL_sk_new_null(void)
|
||||
{
|
||||
return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief free openssl stack object
|
||||
*/
|
||||
void OPENSSL_sk_free(OPENSSL_STACK *stack)
|
||||
{
|
||||
SSL_ASSERT(stack);
|
||||
|
||||
ssl_mem_free(stack->data);
|
||||
ssl_mem_free(stack);
|
||||
}
|
267
components/openssl/library/ssl_x509.c
Normal file
267
components/openssl/library/ssl_x509.c
Normal file
@@ -0,0 +1,267 @@
|
||||
// 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.
|
||||
|
||||
#include "ssl_x509.h"
|
||||
#include "ssl_methods.h"
|
||||
#include "ssl_dbg.h"
|
||||
#include "ssl_port.h"
|
||||
|
||||
/**
|
||||
* @brief show X509 certification information
|
||||
*/
|
||||
int __X509_show_info(X509 *x)
|
||||
{
|
||||
return X509_METHOD_CALL(show_info, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief create a X509 certification object according to input X509 certification
|
||||
*/
|
||||
X509* __X509_new(X509 *ix)
|
||||
{
|
||||
int ret;
|
||||
X509 *x;
|
||||
|
||||
x = ssl_mem_zalloc(sizeof(X509));
|
||||
if (!x)
|
||||
SSL_RET(failed1, "ssl_mem_zalloc\n");
|
||||
|
||||
if (ix)
|
||||
x->method = ix->method;
|
||||
else
|
||||
x->method = X509_method();
|
||||
|
||||
ret = X509_METHOD_CALL(new, x, ix);
|
||||
if (ret)
|
||||
SSL_RET(failed2, "x509_new\n");
|
||||
|
||||
return x;
|
||||
|
||||
failed2:
|
||||
ssl_mem_free(x);
|
||||
failed1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief create a X509 certification object
|
||||
*/
|
||||
X509* X509_new(void)
|
||||
{
|
||||
return __X509_new(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief free a X509 certification object
|
||||
*/
|
||||
void X509_free(X509 *x)
|
||||
{
|
||||
X509_METHOD_CALL(free, x);
|
||||
|
||||
ssl_mem_free(x);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief load a character certification context into system context. If '*cert' is pointed to the
|
||||
* certification, then load certification into it. Or create a new X509 certification object
|
||||
*/
|
||||
X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len)
|
||||
{
|
||||
int m = 0;
|
||||
int ret;
|
||||
X509 *x;
|
||||
|
||||
SSL_ASSERT(buffer);
|
||||
SSL_ASSERT(len);
|
||||
|
||||
if (cert && *cert) {
|
||||
x = *cert;
|
||||
} else {
|
||||
x = X509_new();
|
||||
if (!x)
|
||||
SSL_RET(failed1, "X509_new\n");
|
||||
m = 1;
|
||||
}
|
||||
|
||||
ret = X509_METHOD_CALL(load, x, buffer, len);
|
||||
if (ret)
|
||||
SSL_RET(failed2, "x509_load\n");
|
||||
|
||||
return x;
|
||||
|
||||
failed2:
|
||||
if (m)
|
||||
X509_free(x);
|
||||
failed1:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set SSL context client CA certification
|
||||
*/
|
||||
int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
|
||||
{
|
||||
SSL_ASSERT(ctx);
|
||||
SSL_ASSERT(x);
|
||||
|
||||
if (ctx->client_CA == x)
|
||||
return 1;
|
||||
|
||||
X509_free(ctx->client_CA);
|
||||
|
||||
ctx->client_CA = x;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief add CA client certification into the SSL
|
||||
*/
|
||||
int SSL_add_client_CA(SSL *ssl, X509 *x)
|
||||
{
|
||||
SSL_ASSERT(ssl);
|
||||
SSL_ASSERT(x);
|
||||
|
||||
if (ssl->client_CA == x)
|
||||
return 1;
|
||||
|
||||
X509_free(ssl->client_CA);
|
||||
|
||||
ssl->client_CA = x;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the SSL context certification
|
||||
*/
|
||||
int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
|
||||
{
|
||||
SSL_ASSERT(ctx);
|
||||
SSL_ASSERT(x);
|
||||
|
||||
if (ctx->cert->x509 == x)
|
||||
return 1;
|
||||
|
||||
X509_free(ctx->cert->x509);
|
||||
|
||||
ctx->cert->x509 = x;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the SSL certification
|
||||
*/
|
||||
int SSL_use_certificate(SSL *ssl, X509 *x)
|
||||
{
|
||||
SSL_ASSERT(ssl);
|
||||
SSL_ASSERT(x);
|
||||
|
||||
if (ssl->cert->x509 == x)
|
||||
return 1;
|
||||
|
||||
X509_free(ssl->cert->x509);
|
||||
|
||||
ssl->cert->x509 = x;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get the SSL certification point
|
||||
*/
|
||||
X509 *SSL_get_certificate(const SSL *ssl)
|
||||
{
|
||||
SSL_ASSERT(ssl);
|
||||
|
||||
return ssl->cert->x509;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load certification into the SSL context
|
||||
*/
|
||||
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
|
||||
const unsigned char *d)
|
||||
{
|
||||
int ret;
|
||||
X509 *x;
|
||||
|
||||
x = d2i_X509(NULL, d, len);
|
||||
if (!x)
|
||||
SSL_RET(failed1, "d2i_X509\n");
|
||||
|
||||
ret = SSL_CTX_use_certificate(ctx, x);
|
||||
if (!ret)
|
||||
SSL_RET(failed2, "SSL_CTX_use_certificate\n");
|
||||
|
||||
return 1;
|
||||
|
||||
failed2:
|
||||
X509_free(x);
|
||||
failed1:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load certification into the SSL
|
||||
*/
|
||||
int SSL_use_certificate_ASN1(SSL *ssl, int len,
|
||||
const unsigned char *d)
|
||||
{
|
||||
int ret;
|
||||
X509 *x;
|
||||
|
||||
x = d2i_X509(NULL, d, len);
|
||||
if (!x)
|
||||
SSL_RET(failed1, "d2i_X509\n");
|
||||
|
||||
ret = SSL_use_certificate(ssl, x);
|
||||
if (!ret)
|
||||
SSL_RET(failed2, "SSL_use_certificate\n");
|
||||
|
||||
return 1;
|
||||
|
||||
failed2:
|
||||
X509_free(x);
|
||||
failed1:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load the certification file into SSL context
|
||||
*/
|
||||
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load the certification file into SSL
|
||||
*/
|
||||
int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief get peer certification
|
||||
*/
|
||||
X509 *SSL_get_peer_certificate(const SSL *ssl)
|
||||
{
|
||||
SSL_ASSERT(ssl);
|
||||
|
||||
return ssl->session->peer;
|
||||
}
|
||||
|
597
components/openssl/platform/ssl_pm.c
Normal file
597
components/openssl/platform/ssl_pm.c
Normal file
@@ -0,0 +1,597 @@
|
||||
// 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.
|
||||
|
||||
#include "ssl_pm.h"
|
||||
#include "ssl_port.h"
|
||||
#include "ssl_dbg.h"
|
||||
|
||||
/* mbedtls include */
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/net.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/certs.h"
|
||||
|
||||
#if 0
|
||||
#define DEBUG_LOAD_BUF_STRING(str) SSL_DEBUG(1, "%s\n", str)
|
||||
#else
|
||||
#define DEBUG_LOAD_BUF_STRING(str)
|
||||
#endif
|
||||
|
||||
#define X509_INFO_STRING_LENGTH 1024
|
||||
|
||||
struct ssl_pm
|
||||
{
|
||||
/* local socket file description */
|
||||
mbedtls_net_context fd;
|
||||
/* remote client socket file description */
|
||||
mbedtls_net_context cl_fd;
|
||||
|
||||
mbedtls_ssl_config conf;
|
||||
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
|
||||
mbedtls_ssl_context ssl;
|
||||
|
||||
mbedtls_entropy_context entropy;
|
||||
};
|
||||
|
||||
struct x509_pm
|
||||
{
|
||||
mbedtls_x509_crt *x509_crt;
|
||||
|
||||
mbedtls_x509_crt *ex_crt;
|
||||
};
|
||||
|
||||
struct pkey_pm
|
||||
{
|
||||
mbedtls_pk_context *pkey;
|
||||
|
||||
mbedtls_pk_context *ex_pkey;
|
||||
};
|
||||
|
||||
|
||||
unsigned int max_content_len;
|
||||
|
||||
|
||||
/*********************************************************************************************/
|
||||
/************************************ SSL arch interface *************************************/
|
||||
|
||||
/**
|
||||
* @brief create SSL low-level object
|
||||
*/
|
||||
int ssl_pm_new(SSL *ssl)
|
||||
{
|
||||
struct ssl_pm *ssl_pm;
|
||||
int ret;
|
||||
|
||||
const unsigned char pers[] = "OpenSSL PM";
|
||||
size_t pers_len = sizeof(pers);
|
||||
|
||||
int endpoint;
|
||||
int version;
|
||||
|
||||
const SSL_METHOD *method = ssl->method;
|
||||
|
||||
ssl_pm = ssl_mem_zalloc(sizeof(struct ssl_pm));
|
||||
if (!ssl_pm)
|
||||
SSL_ERR(ret, failed1, "ssl_mem_zalloc\n");
|
||||
|
||||
if (ssl->ctx->read_buffer_len < 2048 ||
|
||||
ssl->ctx->read_buffer_len > 8192)
|
||||
return -1;
|
||||
|
||||
max_content_len = ssl->ctx->read_buffer_len;
|
||||
|
||||
mbedtls_net_init(&ssl_pm->fd);
|
||||
mbedtls_net_init(&ssl_pm->cl_fd);
|
||||
|
||||
mbedtls_ssl_config_init(&ssl_pm->conf);
|
||||
mbedtls_ctr_drbg_init(&ssl_pm->ctr_drbg);
|
||||
mbedtls_entropy_init(&ssl_pm->entropy);
|
||||
mbedtls_ssl_init(&ssl_pm->ssl);
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, pers, pers_len);
|
||||
if (ret)
|
||||
SSL_ERR(ret, failed2, "mbedtls_ctr_drbg_seed:[-0x%x]\n", -ret);
|
||||
|
||||
if (method->endpoint) {
|
||||
endpoint = MBEDTLS_SSL_IS_SERVER;
|
||||
} else {
|
||||
endpoint = MBEDTLS_SSL_IS_CLIENT;
|
||||
}
|
||||
ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
if (ret)
|
||||
SSL_ERR(ret, failed2, "mbedtls_ssl_config_defaults:[-0x%x]\n", -ret);
|
||||
|
||||
if (TLS_ANY_VERSION != ssl->version) {
|
||||
if (TLS1_2_VERSION == ssl->version)
|
||||
version = MBEDTLS_SSL_MINOR_VERSION_3;
|
||||
else if (TLS1_1_VERSION == ssl->version)
|
||||
version = MBEDTLS_SSL_MINOR_VERSION_2;
|
||||
else if (TLS1_VERSION == ssl->version)
|
||||
version = MBEDTLS_SSL_MINOR_VERSION_1;
|
||||
else
|
||||
version = MBEDTLS_SSL_MINOR_VERSION_0;
|
||||
|
||||
mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version);
|
||||
mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version);
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg);
|
||||
|
||||
mbedtls_ssl_conf_dbg(&ssl_pm->conf, NULL, NULL);
|
||||
|
||||
ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf);
|
||||
if (ret)
|
||||
SSL_ERR(ret, failed3, "mbedtls_ssl_setup:[-0x%x]\n", -ret);
|
||||
|
||||
mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL);
|
||||
|
||||
ssl->ssl_pm = ssl_pm;
|
||||
|
||||
return 0;
|
||||
|
||||
failed3:
|
||||
mbedtls_ssl_config_free(&ssl_pm->conf);
|
||||
mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg);
|
||||
failed2:
|
||||
mbedtls_entropy_free(&ssl_pm->entropy);
|
||||
ssl_mem_free(ssl_pm);
|
||||
failed1:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief free SSL low-level object
|
||||
*/
|
||||
void ssl_pm_free(SSL *ssl)
|
||||
{
|
||||
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
|
||||
|
||||
mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg);
|
||||
mbedtls_entropy_free(&ssl_pm->entropy);
|
||||
mbedtls_ssl_config_free(&ssl_pm->conf);
|
||||
mbedtls_ssl_free(&ssl_pm->ssl);
|
||||
|
||||
ssl_mem_free(ssl_pm);
|
||||
ssl->ssl_pm = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief reload SSL low-level certification object
|
||||
*/
|
||||
static int ssl_pm_reload_crt(SSL *ssl)
|
||||
{
|
||||
int ret;
|
||||
int mode;
|
||||
struct ssl_pm *ssl_pm = ssl->ssl_pm;
|
||||
struct x509_pm *ca_pm = (struct x509_pm *)ssl->client_CA->x509_pm;
|
||||
|
||||
struct pkey_pm *pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm;
|
||||
struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm;
|
||||
|
||||
if (ssl->verify_mode == SSL_VERIFY_PEER)
|
||||
mode = MBEDTLS_SSL_VERIFY_REQUIRED;
|
||||
else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
|
||||
mode = MBEDTLS_SSL_VERIFY_OPTIONAL;
|
||||
else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE)
|
||||
mode = MBEDTLS_SSL_VERIFY_UNSET;
|
||||
else
|
||||
mode = MBEDTLS_SSL_VERIFY_NONE;
|
||||
|
||||
mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode);
|
||||
|
||||
if (ca_pm->x509_crt) {
|
||||
mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL);
|
||||
} else if (ca_pm->ex_crt) {
|
||||
mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->ex_crt, NULL);
|
||||
}
|
||||
|
||||
if (crt_pm->x509_crt && pkey_pm->pkey) {
|
||||
ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->x509_crt, pkey_pm->pkey);
|
||||
} else if (crt_pm->ex_crt && pkey_pm->ex_pkey) {
|
||||
ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->ex_crt, pkey_pm->ex_pkey);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ssl_pm_handshake(SSL *ssl)
|
||||
{
|
||||
int ret, mbed_ret;
|
||||
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
|
||||
|
||||
mbed_ret = ssl_pm_reload_crt(ssl);
|
||||
if (mbed_ret)
|
||||
return 0;
|
||||
|
||||
ssl_speed_up_enter();
|
||||
while((mbed_ret = mbedtls_ssl_handshake(&ssl_pm->ssl)) != 0) {
|
||||
if (mbed_ret != MBEDTLS_ERR_SSL_WANT_READ && mbed_ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ssl_speed_up_exit();
|
||||
|
||||
if (!mbed_ret) {
|
||||
struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm;
|
||||
|
||||
ret = 1;
|
||||
|
||||
x509_pm->ex_crt = (mbedtls_x509_crt *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl);
|
||||
} else {
|
||||
ret = 0;
|
||||
SSL_DEBUG(1, "mbedtls_ssl_handshake [-0x%x]\n", -mbed_ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssl_pm_shutdown(SSL *ssl)
|
||||
{
|
||||
int ret, mbed_ret;
|
||||
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
|
||||
|
||||
mbed_ret = mbedtls_ssl_close_notify(&ssl_pm->ssl);
|
||||
if (!mbed_ret) {
|
||||
struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm;
|
||||
|
||||
ret = 0;
|
||||
|
||||
x509_pm->ex_crt = NULL;
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssl_pm_clear(SSL *ssl)
|
||||
{
|
||||
return ssl_pm_shutdown(ssl);
|
||||
}
|
||||
|
||||
|
||||
int ssl_pm_read(SSL *ssl, void *buffer, int len)
|
||||
{
|
||||
int ret, mbed_ret;
|
||||
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
|
||||
|
||||
mbed_ret = mbedtls_ssl_read(&ssl_pm->ssl, buffer, len);
|
||||
if (mbed_ret < 0)
|
||||
ret = -1;
|
||||
else if (mbed_ret == 0)
|
||||
ret = 0;
|
||||
else
|
||||
ret = mbed_ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssl_pm_send(SSL *ssl, const void *buffer, int len)
|
||||
{
|
||||
int ret, mbed_ret;
|
||||
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
|
||||
|
||||
mbed_ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len);
|
||||
if (mbed_ret < 0)
|
||||
ret = -1;
|
||||
else if (mbed_ret == 0)
|
||||
ret = 0;
|
||||
else
|
||||
ret = mbed_ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssl_pm_pending(const SSL *ssl)
|
||||
{
|
||||
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
|
||||
|
||||
return mbedtls_ssl_get_bytes_avail(&ssl_pm->ssl);
|
||||
}
|
||||
|
||||
void ssl_pm_set_fd(SSL *ssl, int fd, int mode)
|
||||
{
|
||||
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
|
||||
|
||||
ssl_pm->fd.fd = fd;
|
||||
}
|
||||
|
||||
int ssl_pm_get_fd(const SSL *ssl, int mode)
|
||||
{
|
||||
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
|
||||
|
||||
return ssl_pm->fd.fd;
|
||||
}
|
||||
|
||||
OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl)
|
||||
{
|
||||
OSSL_HANDSHAKE_STATE state;
|
||||
|
||||
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
|
||||
|
||||
switch (ssl_pm->ssl.state)
|
||||
{
|
||||
case MBEDTLS_SSL_CLIENT_HELLO:
|
||||
state = TLS_ST_CW_CLNT_HELLO;
|
||||
break;
|
||||
case MBEDTLS_SSL_SERVER_HELLO:
|
||||
state = TLS_ST_SW_SRVR_HELLO;
|
||||
break;
|
||||
case MBEDTLS_SSL_SERVER_CERTIFICATE:
|
||||
state = TLS_ST_SW_CERT;
|
||||
break;
|
||||
case MBEDTLS_SSL_SERVER_HELLO_DONE:
|
||||
state = TLS_ST_SW_SRVR_DONE;
|
||||
break;
|
||||
case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
|
||||
state = TLS_ST_CW_KEY_EXCH;
|
||||
break;
|
||||
case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
|
||||
state = TLS_ST_CW_CHANGE;
|
||||
break;
|
||||
case MBEDTLS_SSL_CLIENT_FINISHED:
|
||||
state = TLS_ST_CW_FINISHED;
|
||||
break;
|
||||
case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
|
||||
state = TLS_ST_SW_CHANGE;
|
||||
break;
|
||||
case MBEDTLS_SSL_SERVER_FINISHED:
|
||||
state = TLS_ST_SW_FINISHED;
|
||||
break;
|
||||
case MBEDTLS_SSL_CLIENT_CERTIFICATE:
|
||||
state = TLS_ST_CW_CERT;
|
||||
break;
|
||||
case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
|
||||
state = TLS_ST_SR_KEY_EXCH;
|
||||
break;
|
||||
case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET:
|
||||
state = TLS_ST_SW_SESSION_TICKET;
|
||||
break;
|
||||
case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:
|
||||
state = TLS_ST_SW_CERT_REQ;
|
||||
break;
|
||||
case MBEDTLS_SSL_HANDSHAKE_OVER:
|
||||
state = TLS_ST_OK;
|
||||
break;
|
||||
default :
|
||||
state = TLS_ST_BEFORE;
|
||||
break;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
int x509_pm_show_info(X509 *x)
|
||||
{
|
||||
int ret;
|
||||
char *buf;
|
||||
mbedtls_x509_crt *x509_crt;
|
||||
struct x509_pm *x509_pm = x->x509_pm;
|
||||
|
||||
if (x509_pm->x509_crt)
|
||||
x509_crt = x509_pm->x509_crt;
|
||||
else if (x509_pm->ex_crt)
|
||||
x509_crt = x509_pm->ex_crt;
|
||||
else
|
||||
x509_crt = NULL;
|
||||
|
||||
if (!x509_crt)
|
||||
return -1;
|
||||
|
||||
buf = ssl_mem_malloc(X509_INFO_STRING_LENGTH);
|
||||
if (!buf)
|
||||
SSL_RET(failed1, "");
|
||||
|
||||
ret = mbedtls_x509_crt_info(buf, X509_INFO_STRING_LENGTH - 1, "", x509_crt);
|
||||
if (ret <= 0)
|
||||
SSL_RET(failed2, "");
|
||||
buf[ret] = 0;
|
||||
|
||||
ssl_mem_free(buf);
|
||||
|
||||
SSL_DEBUG(1, "%s", buf);
|
||||
|
||||
return 0;
|
||||
|
||||
failed2:
|
||||
ssl_mem_free(buf);
|
||||
failed1:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int x509_pm_new(X509 *x, X509 *m_x)
|
||||
{
|
||||
struct x509_pm *x509_pm;
|
||||
|
||||
x509_pm = ssl_mem_zalloc(sizeof(struct x509_pm));
|
||||
if (!x509_pm)
|
||||
SSL_RET(failed1, "ssl_mem_zalloc\n");
|
||||
|
||||
x->x509_pm = x509_pm;
|
||||
|
||||
if (m_x) {
|
||||
struct x509_pm *m_x509_pm = (struct x509_pm *)m_x->x509_pm;
|
||||
|
||||
x509_pm->ex_crt = m_x509_pm->x509_crt;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failed1:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void x509_pm_free(X509 *x)
|
||||
{
|
||||
struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm;
|
||||
|
||||
if (x509_pm->x509_crt) {
|
||||
mbedtls_x509_crt_free(x509_pm->x509_crt);
|
||||
|
||||
ssl_mem_free(x509_pm->x509_crt);
|
||||
x509_pm->x509_crt = NULL;
|
||||
}
|
||||
|
||||
ssl_mem_free(x->x509_pm);
|
||||
x->x509_pm = NULL;
|
||||
}
|
||||
|
||||
int x509_pm_load(X509 *x, const unsigned char *buffer, int len)
|
||||
{
|
||||
int ret;
|
||||
unsigned char *load_buf;
|
||||
struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm;
|
||||
|
||||
if (x509_pm->x509_crt)
|
||||
mbedtls_x509_crt_free(x509_pm->x509_crt);
|
||||
|
||||
if (!x509_pm->x509_crt) {
|
||||
x509_pm->x509_crt = ssl_mem_malloc(sizeof(mbedtls_x509_crt));
|
||||
if (!x509_pm->x509_crt)
|
||||
SSL_RET(failed1, "ssl_mem_malloc\n");
|
||||
}
|
||||
|
||||
load_buf = ssl_mem_malloc(len + 1);
|
||||
if (!load_buf)
|
||||
SSL_RET(failed2, "ssl_mem_malloc\n");
|
||||
|
||||
ssl_memcpy(load_buf, buffer, len);
|
||||
load_buf[len] = '\0';
|
||||
|
||||
DEBUG_LOAD_BUF_STRING(load_buf);
|
||||
|
||||
mbedtls_x509_crt_init(x509_pm->x509_crt);
|
||||
|
||||
ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len + 1);
|
||||
ssl_mem_free(load_buf);
|
||||
|
||||
if (ret)
|
||||
SSL_RET(failed2, "mbedtls_x509_crt_parse, return [-0x%x]\n", -ret);
|
||||
|
||||
return 0;
|
||||
|
||||
failed2:
|
||||
ssl_mem_free(x509_pm->x509_crt);
|
||||
x509_pm->x509_crt = NULL;
|
||||
failed1:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pkey)
|
||||
{
|
||||
struct pkey_pm *pkey_pm;
|
||||
|
||||
pkey_pm = ssl_mem_zalloc(sizeof(struct pkey_pm));
|
||||
if (!pkey_pm)
|
||||
return -1;
|
||||
|
||||
pk->pkey_pm = pkey_pm;
|
||||
|
||||
if (m_pkey) {
|
||||
struct pkey_pm *m_pkey_pm = (struct pkey_pm *)m_pkey->pkey_pm;
|
||||
|
||||
pkey_pm->ex_pkey = m_pkey_pm->pkey;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pkey_pm_free(EVP_PKEY *pk)
|
||||
{
|
||||
struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm;
|
||||
|
||||
if (pkey_pm->pkey) {
|
||||
mbedtls_pk_free(pkey_pm->pkey);
|
||||
|
||||
ssl_mem_free(pkey_pm->pkey);
|
||||
pkey_pm->pkey = NULL;
|
||||
}
|
||||
|
||||
ssl_mem_free(pk->pkey_pm);
|
||||
pk->pkey_pm = NULL;
|
||||
}
|
||||
|
||||
int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len)
|
||||
{
|
||||
int ret;
|
||||
unsigned char *load_buf;
|
||||
struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm;
|
||||
|
||||
if (pkey_pm->pkey)
|
||||
mbedtls_pk_free(pkey_pm->pkey);
|
||||
|
||||
if (!pkey_pm->pkey) {
|
||||
pkey_pm->pkey = ssl_mem_malloc(sizeof(mbedtls_pk_context));
|
||||
if (!pkey_pm->pkey)
|
||||
SSL_RET(failed1, "ssl_mem_malloc\n");
|
||||
}
|
||||
|
||||
load_buf = ssl_mem_malloc(len + 1);
|
||||
if (!load_buf)
|
||||
SSL_RET(failed2, "ssl_mem_malloc\n");
|
||||
|
||||
ssl_memcpy(load_buf, buffer, len);
|
||||
load_buf[len] = '\0';
|
||||
|
||||
DEBUG_LOAD_BUF_STRING(load_buf);
|
||||
|
||||
mbedtls_pk_init(pkey_pm->pkey);
|
||||
|
||||
ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len + 1, NULL, 0);
|
||||
ssl_mem_free(load_buf);
|
||||
|
||||
if (ret)
|
||||
SSL_RET(failed2, "mbedtls_pk_parse_key, return [-0x%x]\n", -ret);
|
||||
|
||||
return 0;
|
||||
|
||||
failed2:
|
||||
ssl_mem_free(pkey_pm->pkey);
|
||||
pkey_pm->pkey = NULL;
|
||||
failed1:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ssl_pm_set_bufflen(SSL *ssl, int len)
|
||||
{
|
||||
max_content_len = len;
|
||||
}
|
||||
|
||||
long ssl_pm_get_verify_result(const SSL *ssl)
|
||||
{
|
||||
long ret;
|
||||
long verify_result;
|
||||
struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm;
|
||||
|
||||
ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl);
|
||||
|
||||
if (!ret)
|
||||
verify_result = X509_V_OK;
|
||||
else
|
||||
verify_result = X509_V_ERR_UNSPECIFIED;
|
||||
|
||||
return verify_result;
|
||||
}
|
66
components/openssl/platform/ssl_port.c
Normal file
66
components/openssl/platform/ssl_port.c
Normal file
@@ -0,0 +1,66 @@
|
||||
// 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.
|
||||
|
||||
#include "ssl_port.h"
|
||||
|
||||
#ifdef ESP32_IDF_PLATFORM
|
||||
|
||||
#include "string.h"
|
||||
#include "malloc.h"
|
||||
|
||||
/*********************************************************************************************/
|
||||
/********************************* SSL general interface *************************************/
|
||||
|
||||
void* ssl_mem_zalloc(size_t size)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
|
||||
if (p)
|
||||
memset(p, 0, size);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *ssl_mem_malloc(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void ssl_mem_free(void *p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
void* ssl_memcpy(void *to, const void *from, size_t size)
|
||||
{
|
||||
return memcpy(to, from, size);
|
||||
}
|
||||
|
||||
size_t ssl_strlen(const char *src)
|
||||
{
|
||||
return strlen(src);
|
||||
}
|
||||
|
||||
void ssl_speed_up_enter(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ssl_speed_up_exit(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -39,7 +39,7 @@ static spi_flash_counters_t s_flash_stats;
|
||||
#define COUNTER_STOP(counter) \
|
||||
do{ \
|
||||
s_flash_stats.counter.count++; \
|
||||
s_flash_stats.counter.time += (xthal_get_ccount() - ts_begin) / (XT_CLOCK_FREQ / 1000000); \\
|
||||
s_flash_stats.counter.time += (xthal_get_ccount() - ts_begin) / (XT_CLOCK_FREQ / 1000000); \
|
||||
} while(0)
|
||||
|
||||
#define COUNTER_ADD_BYTES(counter, size) \
|
||||
@@ -126,10 +126,6 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size)
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const void *src, size_t size)
|
||||
{
|
||||
// TODO: replace this check with code which deals with unaligned sources
|
||||
if (((ptrdiff_t) src) % 4 != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
// Destination alignment is also checked in ROM code, but we can give
|
||||
// better error code here
|
||||
// TODO: add handling of unaligned destinations
|
||||
|
@@ -74,7 +74,7 @@ esp_err_t spi_flash_erase_range(size_t start_addr, size_t size);
|
||||
/**
|
||||
* @brief Write data to Flash.
|
||||
*
|
||||
* @note Both des_addr and src_addr have to be 4-byte aligned.
|
||||
* @note Address in flash, dest, has to be 4-byte aligned.
|
||||
* This is a temporary limitation which will be removed.
|
||||
*
|
||||
* @param dest destination address in Flash
|
||||
@@ -88,7 +88,7 @@ esp_err_t spi_flash_write(size_t dest, const void *src, size_t size);
|
||||
/**
|
||||
* @brief Read data from Flash.
|
||||
*
|
||||
* @note Both des_addr and src_addr have to be 4-byte aligned.
|
||||
* @note Both src and dest have to be 4-byte aligned.
|
||||
* This is a temporary limitation which will be removed.
|
||||
*
|
||||
* @param src source address of the data in Flash.
|
||||
|
@@ -1,3 +1,6 @@
|
||||
Copyrights and Licenses
|
||||
***********************
|
||||
|
||||
Software Copyrights
|
||||
===================
|
||||
|
||||
@@ -87,8 +90,7 @@ developments under license policy of following terms.
|
||||
Copyright (C) 2011, ChaN, all right reserved.
|
||||
|
||||
* The TJpgDec module is a free software and there is NO WARRANTY.
|
||||
* No restriction on use. You can use, modify and redistribute it for
|
||||
personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
|
||||
* No restriction on use. You can use, modify and redistribute it for personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
|
||||
* Redistributions of source code must retain the above copyright notice.
|
||||
|
||||
|
||||
|
22
docs/Doxyfile
Normal file
22
docs/Doxyfile
Normal file
@@ -0,0 +1,22 @@
|
||||
PROJECT_NAME = "ESP32 Programming Guide"
|
||||
|
||||
INPUT = ../components/esp32/include/esp_wifi.h ../components/driver/include/driver ../components/esp32/include/rom/gpio.h ../components/bt/include ../components/nvs_flash/include ../components/log/include ../components/vfs/include
|
||||
|
||||
WARN_NO_PARAMDOC = YES
|
||||
|
||||
RECURSIVE = NO
|
||||
CASE_SENSE_NAMES = NO
|
||||
EXTRACT_ALL = NO
|
||||
|
||||
GENERATE_XML = YES
|
||||
XML_OUTPUT = xml
|
||||
|
||||
GENERATE_HTML = NO
|
||||
HAVE_DOT = NO
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_MAN = NO
|
||||
GENERATE_RTF = NO
|
||||
|
||||
QUIET = YES
|
||||
WARN_LOGFILE = "doxygen-warning-log.txt"
|
||||
|
177
docs/Makefile
Normal file
177
docs/Makefile
Normal file
@@ -0,0 +1,177 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# User-friendly check for sphinx-build
|
||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
||||
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
|
||||
endif
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " xml to make Docutils-native XML files"
|
||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/ReadtheDocsTemplate"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ReadtheDocsTemplate"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
xml:
|
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
pseudoxml:
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
BIN
docs/_static/doc-code-documentation-inline.png
vendored
Normal file
BIN
docs/_static/doc-code-documentation-inline.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 51 KiB |
BIN
docs/_static/doc-code-documentation-rendered.png
vendored
Normal file
BIN
docs/_static/doc-code-documentation-rendered.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
BIN
docs/_static/doc-code-function.png
vendored
Normal file
BIN
docs/_static/doc-code-function.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 190 KiB |
BIN
docs/_static/doc-code-member.png
vendored
Normal file
BIN
docs/_static/doc-code-member.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
BIN
docs/_static/doc-code-void-function.png
vendored
Normal file
BIN
docs/_static/doc-code-void-function.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
31
docs/api/bt.rst
Normal file
31
docs/api/bt.rst
Normal file
@@ -0,0 +1,31 @@
|
||||
Bluetooth API
|
||||
=============
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
`Instructions <http://esp-idf.readthedocs.io/en/latest/api/template.html>`_
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
`Instructions <http://esp-idf.readthedocs.io/en/latest/api/template.html>`_
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
`Instructions <http://esp-idf.readthedocs.io/en/latest/api/template.html>`_
|
||||
|
||||
Type Definitions
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. doxygenstruct:: vhci_host_callback
|
||||
|
||||
Functions
|
||||
^^^^^^^^^
|
||||
|
||||
.. doxygenfunction:: API_vhci_host_check_send_available
|
||||
.. doxygenfunction:: API_vhci_host_register_callback
|
||||
.. doxygenfunction:: API_vhci_host_send_packet
|
||||
.. doxygenfunction:: bt_controller_init
|
||||
|
74
docs/api/esp_wifi.rst
Normal file
74
docs/api/esp_wifi.rst
Normal file
@@ -0,0 +1,74 @@
|
||||
Wi-Fi API
|
||||
=========
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
`Instructions <http://esp-idf.readthedocs.io/en/latest/api/template.html>`_
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
`Instructions <http://esp-idf.readthedocs.io/en/latest/api/template.html>`_
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
`Instructions <http://esp-idf.readthedocs.io/en/latest/api/template.html>`_
|
||||
|
||||
Macros
|
||||
------
|
||||
|
||||
.. doxygendefine:: WIFI_INIT_CONFIG_DEFAULT
|
||||
|
||||
|
||||
Typedefs
|
||||
--------
|
||||
|
||||
.. doxygentypedef:: wifi_promiscuous_cb_t
|
||||
.. doxygentypedef:: wifi_rxcb_t
|
||||
.. doxygentypedef:: esp_vendor_ie_cb_t
|
||||
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. doxygenfunction:: esp_wifi_init
|
||||
.. doxygenfunction:: esp_wifi_deinit
|
||||
.. doxygenfunction:: esp_wifi_set_mode
|
||||
.. doxygenfunction:: esp_wifi_get_mode
|
||||
.. doxygenfunction:: esp_wifi_start
|
||||
.. doxygenfunction:: esp_wifi_stop
|
||||
.. doxygenfunction:: esp_wifi_connect
|
||||
.. doxygenfunction:: esp_wifi_disconnect
|
||||
.. doxygenfunction:: esp_wifi_clear_fast_connect
|
||||
.. doxygenfunction:: esp_wifi_kick_station
|
||||
.. doxygenfunction:: esp_wifi_scan_start
|
||||
.. doxygenfunction:: esp_wifi_scan_stop
|
||||
.. doxygenfunction:: esp_wifi_get_ap_num
|
||||
.. doxygenfunction:: esp_wifi_get_ap_list
|
||||
.. doxygenfunction:: esp_wifi_set_ps
|
||||
.. doxygenfunction:: esp_wifi_get_ps
|
||||
.. doxygenfunction:: esp_wifi_set_protocol
|
||||
.. doxygenfunction:: esp_wifi_get_protocol
|
||||
.. doxygenfunction:: esp_wifi_set_bandwidth
|
||||
.. doxygenfunction:: esp_wifi_get_bandwidth
|
||||
.. doxygenfunction:: esp_wifi_set_channel
|
||||
.. doxygenfunction:: esp_wifi_get_channel
|
||||
.. doxygenfunction:: esp_wifi_set_country
|
||||
.. doxygenfunction:: esp_wifi_get_country
|
||||
.. doxygenfunction:: esp_wifi_set_mac
|
||||
.. doxygenfunction:: esp_wifi_get_mac
|
||||
.. doxygenfunction:: esp_wifi_set_promiscuous_rx_cb
|
||||
.. doxygenfunction:: esp_wifi_set_promiscuous
|
||||
.. doxygenfunction:: esp_wifi_get_promiscuous
|
||||
.. doxygenfunction:: esp_wifi_set_config
|
||||
.. doxygenfunction:: esp_wifi_get_config
|
||||
.. doxygenfunction:: esp_wifi_get_station_list
|
||||
.. doxygenfunction:: esp_wifi_free_station_list
|
||||
.. doxygenfunction:: esp_wifi_set_storage
|
||||
.. doxygenfunction:: esp_wifi_reg_rxcb
|
||||
.. doxygenfunction:: esp_wifi_set_auto_connect
|
||||
.. doxygenfunction:: esp_wifi_get_auto_connect
|
||||
.. doxygenfunction:: esp_wifi_set_vendor_ie
|
||||
.. doxygenfunction:: esp_wifi_set_vendor_ie_cb
|
90
docs/api/gpio.rst
Normal file
90
docs/api/gpio.rst
Normal file
@@ -0,0 +1,90 @@
|
||||
GPIO API
|
||||
========
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
`Instructions <http://esp-idf.readthedocs.io/en/latest/api/template.html>`_
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
`Instructions <http://esp-idf.readthedocs.io/en/latest/api/template.html>`_
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
`Instructions <http://esp-idf.readthedocs.io/en/latest/api/template.html>`_
|
||||
|
||||
Enumerations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
.. doxygenenum:: gpio_int_type_t
|
||||
.. doxygenenum:: gpio_mode_t
|
||||
.. doxygenenum:: gpio_pull_mode_t
|
||||
|
||||
Functions
|
||||
^^^^^^^^^
|
||||
|
||||
.. doxygenfunction:: gpio_config
|
||||
.. doxygenfunction:: gpio_set_intr_type
|
||||
.. doxygenfunction:: gpio_intr_enable
|
||||
.. doxygenfunction:: gpio_intr_disable
|
||||
.. doxygenfunction:: gpio_set_level
|
||||
.. doxygenfunction:: gpio_get_level
|
||||
.. doxygenfunction:: gpio_set_direction
|
||||
.. doxygenfunction:: gpio_set_pull_mode
|
||||
.. doxygenfunction:: gpio_wakeup_enable
|
||||
.. doxygenfunction:: gpio_wakeup_disable
|
||||
.. doxygenfunction:: gpio_isr_register
|
||||
|
||||
*Example code:* Configuration of GPIO as an output
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
|
||||
io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode
|
||||
io_conf.pin_bit_mask = GPIO_SEL_18 | GPIO_SEL_19; //bit mask of the pins that you want to set,e.g.GPIO18/19
|
||||
io_conf.pull_down_en = 0; //disable pull-down mode
|
||||
io_conf.pull_up_en = 0; //disable pull-up mode
|
||||
gpio_config(&io_conf); //configure GPIO with the given settings
|
||||
|
||||
*Example code:* Configuration of GPIO as an input
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt
|
||||
io_conf.mode = GPIO_MODE_INPUT; //set as input
|
||||
io_conf.pin_bit_mask = GPIO_SEL_4 | GPIO_SEL_5; //bit mask of the pins that you want to set, e.g.,GPIO4/5
|
||||
io_conf.pull_down_en = 0; //disable pull-down mode
|
||||
io_conf.pull_up_en = 1; //enable pull-up mode
|
||||
gpio_config(&io_conf); //configure GPIO with the given settings
|
||||
|
||||
|
||||
ROM GPIO functions
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. doxygenfunction:: gpio_init
|
||||
.. doxygenfunction:: gpio_output_set
|
||||
.. doxygenfunction:: gpio_output_set_high
|
||||
.. doxygenfunction:: gpio_input_get
|
||||
.. doxygenfunction:: gpio_input_get_high
|
||||
.. doxygenfunction:: gpio_intr_handler_register
|
||||
.. doxygenfunction:: gpio_intr_pending
|
||||
.. doxygenfunction:: gpio_intr_pending_high
|
||||
.. doxygenfunction:: gpio_intr_ack
|
||||
.. doxygenfunction:: gpio_intr_ack_high
|
||||
.. doxygenfunction:: gpio_pin_wakeup_enable
|
||||
.. doxygenfunction:: gpio_pin_wakeup_disable
|
||||
.. doxygenfunction:: gpio_matrix_in
|
||||
.. doxygenfunction:: gpio_matrix_out
|
||||
.. doxygenfunction:: gpio_pad_select_gpio
|
||||
.. doxygenfunction:: gpio_pad_set_drv
|
||||
.. doxygenfunction:: gpio_pad_pullup
|
||||
.. doxygenfunction:: gpio_pad_pulldown
|
||||
.. doxygenfunction:: gpio_pad_unhold
|
||||
.. doxygenfunction:: gpio_pad_hold
|
||||
|
||||
|
19
docs/api/log.rst
Normal file
19
docs/api/log.rst
Normal file
@@ -0,0 +1,19 @@
|
||||
.. include:: ../../components/log/README.rst
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
Enumerations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
.. doxygenenum:: esp_log_level_t
|
||||
|
||||
Functions
|
||||
^^^^^^^^^
|
||||
|
||||
.. doxygenfunction:: esp_log_level_set
|
||||
.. doxygenfunction:: esp_log_set_vprintf
|
||||
.. doxygenfunction:: esp_log_timestamp
|
||||
.. doxygenfunction:: esp_log_write
|
||||
|
||||
|
68
docs/api/nvs.rst
Normal file
68
docs/api/nvs.rst
Normal file
@@ -0,0 +1,68 @@
|
||||
.. include:: ../../components/nvs_flash/README.rst
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
Enumerations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
.. doxygenenum:: nvs_open_mode
|
||||
|
||||
Functions
|
||||
^^^^^^^^^
|
||||
|
||||
.. doxygenfunction:: nvs_flash_init
|
||||
.. doxygenfunction:: nvs_flash_init_custom
|
||||
|
||||
.. doxygenfunction:: nvs_open
|
||||
|
||||
*Note: the following nvs_set_X function are "the same" except the data type accepted*
|
||||
|
||||
.. doxygenfunction:: nvs_set_i8
|
||||
.. doxygenfunction:: nvs_set_u8
|
||||
.. doxygenfunction:: nvs_set_i16
|
||||
.. doxygenfunction:: nvs_set_u16
|
||||
.. doxygenfunction:: nvs_set_i32
|
||||
.. doxygenfunction:: nvs_set_u32
|
||||
.. doxygenfunction:: nvs_set_i64
|
||||
.. doxygenfunction:: nvs_set_u64
|
||||
.. doxygenfunction:: nvs_set_str
|
||||
.. doxygenfunction:: nvs_set_blob
|
||||
|
||||
*Note: the following nvs_get_X functions are "the same" except the data type returned*
|
||||
|
||||
.. doxygenfunction:: nvs_get_i8
|
||||
.. doxygenfunction:: nvs_get_u8
|
||||
.. doxygenfunction:: nvs_get_i16
|
||||
.. doxygenfunction:: nvs_get_u16
|
||||
.. doxygenfunction:: nvs_get_i32
|
||||
.. doxygenfunction:: nvs_get_u32
|
||||
.. doxygenfunction:: nvs_get_i64
|
||||
.. doxygenfunction:: nvs_get_u64
|
||||
.. doxygenfunction:: nvs_get_str
|
||||
.. doxygenfunction:: nvs_get_blob
|
||||
|
||||
.. doxygenfunction:: nvs_erase_key
|
||||
.. doxygenfunction:: nvs_erase_all
|
||||
.. doxygenfunction:: nvs_commit
|
||||
.. doxygenfunction:: nvs_close
|
||||
|
||||
Error codes
|
||||
^^^^^^^^^^^
|
||||
|
||||
.. doxygendefine:: ESP_ERR_NVS_BASE
|
||||
.. doxygendefine:: ESP_ERR_NVS_NOT_INITIALIZED
|
||||
.. doxygendefine:: ESP_ERR_NVS_NOT_FOUND
|
||||
.. doxygendefine:: ESP_ERR_NVS_TYPE_MISMATCH
|
||||
.. doxygendefine:: ESP_ERR_NVS_READ_ONLY
|
||||
.. doxygendefine:: ESP_ERR_NVS_NOT_ENOUGH_SPACE
|
||||
.. doxygendefine:: ESP_ERR_NVS_INVALID_NAME
|
||||
.. doxygendefine:: ESP_ERR_NVS_INVALID_HANDLE
|
||||
.. doxygendefine:: ESP_ERR_NVS_REMOVE_FAILED
|
||||
.. doxygendefine:: ESP_ERR_NVS_KEY_TOO_LONG
|
||||
.. doxygendefine:: ESP_ERR_NVS_PAGE_FULL
|
||||
.. doxygendefine:: ESP_ERR_NVS_INVALID_STATE
|
||||
.. doxygendefine:: ESP_ERR_NVS_INVALID_LENGTH
|
||||
|
||||
|
||||
|
70
docs/api/template.rst
Normal file
70
docs/api/template.rst
Normal file
@@ -0,0 +1,70 @@
|
||||
Template API
|
||||
=============
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
INSTRUCTIONS: Provide overview where and how this API may be used. For large number of functions, break down description into groups.
|
||||
|
||||
Use the folowing heading levels:
|
||||
|
||||
* # with overline, for parts
|
||||
* \* with overline, for chapters
|
||||
* =, for sections
|
||||
* -, for subsections
|
||||
* ^, for subsubsections
|
||||
* ", for paragraphs
|
||||
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
INSTRUCTIONS: Provide one or more pratical examples to demonstrate functionality of this API.
|
||||
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
INSTRUCTIONS: Provide list of API memebers divided into sections. Use coresponding **.. doxygen** directices, so member documentation is auto updated.
|
||||
|
||||
* Data Structures **.. doxygenstruct**
|
||||
* Macros **.. doxygendefine**
|
||||
* Type Definitions **.. doxygentypedef**
|
||||
* Enumerations **.. doxygenenum**
|
||||
* Functions **.. doxygenfunction**
|
||||
* Variables **.. doxygenvariable**
|
||||
|
||||
Include code snippotes to ilustrate functionality of particular functions where applicable. Skip section hearder if empty.
|
||||
|
||||
|
||||
Data Structures
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
.. Data Structures .. doxygenstruct
|
||||
|
||||
Macros
|
||||
^^^^^^
|
||||
|
||||
.. Macros .. doxygendefine
|
||||
|
||||
Type Definitions
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. Type Definitions .. doxygentypedef
|
||||
|
||||
Enumerations
|
||||
^^^^^^^^^^^^
|
||||
|
||||
.. Enumerations .. doxygenenum
|
||||
|
||||
Functions
|
||||
^^^^^^^^^
|
||||
|
||||
.. Functions .. doxygenfunction
|
||||
|
||||
Variables
|
||||
^^^^^^^^^
|
||||
|
||||
.. Variables .. doxygenvariable
|
||||
|
||||
|
27
docs/api/vfs.rst
Normal file
27
docs/api/vfs.rst
Normal file
@@ -0,0 +1,27 @@
|
||||
.. include:: ../../components/vfs/README.rst
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
Defines
|
||||
^^^^^^^
|
||||
|
||||
.. doxygendefine:: ESP_VFS_PATH_MAX
|
||||
.. doxygendefine:: ESP_VFS_FLAG_DEFAULT
|
||||
.. doxygendefine:: ESP_VFS_FLAG_CONTEXT_PTR
|
||||
|
||||
|
||||
Structures
|
||||
^^^^^^^^^^
|
||||
|
||||
.. doxygenstruct:: esp_vfs_t
|
||||
|
||||
Functions
|
||||
^^^^^^^^^
|
||||
|
||||
.. doxygenfunction:: esp_vfs_dev_uart_register
|
||||
.. doxygenfunction:: esp_vfs_register
|
||||
|
||||
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Build System
|
||||
------------
|
||||
************
|
||||
|
||||
This document explains the Espressif IoT Development Framework build system and the
|
||||
concept of "components"
|
||||
|
301
docs/conf.py
Normal file
301
docs/conf.py
Normal file
@@ -0,0 +1,301 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Read the Docs Template documentation build configuration file, created by
|
||||
# sphinx-quickstart on Tue Aug 26 14:19:49 2014.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- Run DoxyGen to prepare XML for Sphinx---------------------------------
|
||||
# ref. https://github.com/rtfd/readthedocs.org/issues/388
|
||||
#
|
||||
# added by krzychb, 24-Oct-2016
|
||||
#
|
||||
|
||||
from subprocess import call, Popen, PIPE
|
||||
import shlex
|
||||
|
||||
call('doxygen')
|
||||
|
||||
# -- Function to get output of a command ----------------------------------
|
||||
def run_cmd_get_output(cmd):
|
||||
process = Popen(shlex.split(cmd), stdout=PIPE)
|
||||
(output, err) = process.communicate()
|
||||
exit_code = process.wait()
|
||||
if exit_code != 0:
|
||||
raise RuntimeError('command line program has failed')
|
||||
return output
|
||||
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = ['breathe']
|
||||
|
||||
# Breathe extension variables
|
||||
breathe_projects = { "esp32-idf": "xml/" }
|
||||
breathe_default_project = "esp32-idf"
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'ESP32 Programming Guide'
|
||||
copyright = u'2016, Espressif'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# This is supposed to be "the short X.Y version", but it's the only version
|
||||
# visible when you open index.html.
|
||||
# Display full version to make things less confusing.
|
||||
# If needed, nearest tag is returned by 'git describe --abbrev=0'.
|
||||
version = run_cmd_get_output('git describe')
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = run_cmd_get_output('git describe')
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'ReadtheDocsTemplatedoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'ReadtheDocsTemplate.tex', u'Read the Docs Template Documentation',
|
||||
u'Read the Docs', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'readthedocstemplate', u'Read the Docs Template Documentation',
|
||||
[u'Read the Docs'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'ReadtheDocsTemplate', u'Read the Docs Template Documentation',
|
||||
u'Read the Docs', 'ReadtheDocsTemplate', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
|
||||
# -- Use sphinx_rtd_theme for local builds --------------------------------
|
||||
# ref. https://github.com/snide/sphinx_rtd_theme#using-this-theme-locally-then-building-on-read-the-docs
|
||||
#
|
||||
# added by krzychb, 24-Oct-2016
|
||||
#
|
||||
# on_rtd is whether we are on readthedocs.org
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
||||
|
||||
# otherwise, readthedocs.org uses their theme by default, so no need to specify it
|
1
docs/contributing.rst
Normal file
1
docs/contributing.rst
Normal file
@@ -0,0 +1 @@
|
||||
.. include:: ../CONTRIBUTING.rst
|
@@ -1,5 +1,5 @@
|
||||
Contributor Agreement
|
||||
---------------------
|
||||
=====================
|
||||
|
||||
Individual Contributor Non-Exclusive License Agreement
|
||||
------------------------------------------------------
|
||||
|
87
docs/deep-sleep-stub.rst
Normal file
87
docs/deep-sleep-stub.rst
Normal file
@@ -0,0 +1,87 @@
|
||||
Deep Sleep Wake Stubs
|
||||
---------------------
|
||||
|
||||
ESP32 supports running a "deep sleep wake stub" when coming out of deep sleep. This function runs immediately as soon as the chip wakes up - before any normal initialisation, bootloader, or ESP-IDF code has run. After the wake stub runs, the SoC can go back to sleep or continue to start ESP-IDF normally.
|
||||
|
||||
Deep sleep wake stub code is loaded into "RTC Fast Memory" and any data which it uses must also be loaded into RTC memory. RTC memory regions hold their contents during deep sleep.
|
||||
|
||||
Rules for Wake Stubs
|
||||
====================
|
||||
|
||||
Wake stub code must be carefully written:
|
||||
|
||||
* As the SoC has freshly woken from sleep, most of the peripherals are in reset states. The SPI flash is unmapped.
|
||||
|
||||
* The wake stub code can only call functions implemented in ROM or loaded into RTC Fast Memory (see below.)
|
||||
|
||||
* The wake stub code can only access data loaded in RTC memory. All other RAM will be unintiailised and have random contents. The wake stub can use other RAM for temporary storage, but the contents will be overwritten when the SoC goes back to sleep or starts ESP-IDF.
|
||||
|
||||
* RTC memory must include any read-only data (.rodata) used by the stub.
|
||||
|
||||
* Data in RTC memory is initialised whenever the SoC restarts, except when waking from deep sleep. When waking from deep sleep, the values which were present before going to sleep are kept.
|
||||
|
||||
* Wake stub code is a part of the main esp-idf app. During normal running of esp-idf, functions can call the wake stub functions or access RTC memory. It is as if these were regular parts of the app.
|
||||
|
||||
Implementing A Stub
|
||||
===================
|
||||
|
||||
The wake stub in esp-idf is called ``esp_wake_deep_sleep()``. This function runs whenever the SoC wakes from deep sleep. There is a default version of this function provided in esp-idf, but the default function is weak-linked so if your app contains a function named ``esp_wake_deep_sleep()` then this will override the default.
|
||||
|
||||
If supplying a custom wake stub, the first thing it does should be to call ``esp_default_wake_deep_sleep()``.
|
||||
|
||||
It is not necessary to implement ``esp_wake_deep_sleep()`` in your app in order to use deep sleep. It is only necessary if you want to have special behaviour immediately on wake.
|
||||
|
||||
If you want to swap between different deep sleep stubs at runtime, it is also possible to do this by calling the ``esp_set_deep_sleep_wake_stub()`` function. This is not necessary if you only use the default ``esp_wake_deep_sleep()`` function.
|
||||
|
||||
All of these functions are declared in the ``esp_deepsleep.h`` header under components/esp32.
|
||||
|
||||
Loading Code Into RTC Memory
|
||||
============================
|
||||
|
||||
Wake stub code must be resident in RTC Fast Memory. This can be done in one of two ways.
|
||||
|
||||
The first way is to use the ``RTC_IRAM_ATTR`` attribute to place a function into RTC memory::
|
||||
|
||||
void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
|
||||
esp_default_wake_deep_sleep();
|
||||
// Add additional functionality here
|
||||
}
|
||||
|
||||
The second way is to place the function into any source file whose name starts with ``rtc_wake_stub``. Files names ``rtc_wake_stub*`` have their contents automatically put into RTC memory by the linker.
|
||||
|
||||
The first way is simpler for very short and simple code, or for source files where you want to mix "normal" and "RTC" code. The second way is simpler when you want to write longer pieces of code for RTC memory.
|
||||
|
||||
|
||||
Loading Data Into RTC Memory
|
||||
============================
|
||||
|
||||
Data used by stub code must be resident in RTC Slow Memory. This memory is also used by the ULP.
|
||||
|
||||
Specifying this data can be done in one of two ways:
|
||||
|
||||
The first way is to use the ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` to specify any data (writeable or read-only, respectivley) which should be loaded into RTC slow memory::
|
||||
|
||||
RTC_DATA_ATTR int wake_count;
|
||||
|
||||
void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
|
||||
esp_default_wake_deep_sleep();
|
||||
static RTC_RODATA_ATTR const char fmt_str[] = "Wake count %d\n";
|
||||
ets_printf(fmt_str, wake_count++);
|
||||
}
|
||||
|
||||
Unfortunately, any string constants used in this way must be declared as arrays and marked with RTC_RODATA_ATTR, as shown in the example above.
|
||||
|
||||
The second way is to place the data into any source file whose name starts with ``rtc_wake_stub``.
|
||||
|
||||
For example, the equivalent example in ``rtc_wake_stub_counter.c``::
|
||||
|
||||
int wake_count;
|
||||
|
||||
void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
|
||||
esp_default_wake_deep_sleep();
|
||||
ets_printf("Wake count %d\n", wake_count++);
|
||||
}
|
||||
|
||||
The second way is a better option if you need to use strings, or write other more complex code.
|
||||
|
||||
|
126
docs/documenting-code.rst
Normal file
126
docs/documenting-code.rst
Normal file
@@ -0,0 +1,126 @@
|
||||
Documenting Code
|
||||
================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
When documenting code for this repository, please follow `Doxygen style <http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html#specialblock>`_. You are doing it by inserting special commands, for instance ``@param``, into standard comments blocks like for example ``/* @param ratio this is oxygen to air ratio */``.
|
||||
|
||||
Doxygen is phrasing the code, extracting the commands together with subsequent text, and building documentation out of it.
|
||||
|
||||
Typical comment block, that contains documentation of a function, looks like below.
|
||||
|
||||
.. image:: _static/doc-code-documentation-inline.png
|
||||
:align: center
|
||||
:alt: Sample inline code documentation
|
||||
|
||||
Doxygen supports couple of formatting styles. It also gives you great flexibility on level of details to include in documentation. To get the taste of available features please check data reach and very well organized `Doxygen Manual <http://www.stack.nl/~dimitri/doxygen/manual/index.html>`_.
|
||||
|
||||
Why we need it?
|
||||
---------------
|
||||
|
||||
The purpose of this description is to provide quick summary on documentation style used in `espressif/esp-idf <https://github.com/espressif/esp-idf>`_ repository.
|
||||
|
||||
The ultimate goal is to ensure that all the code is consistently documented, so we can use tools like `Sphinx <http://www.sphinx-doc.org/>`_ and `Breathe <https://breathe.readthedocs.io/>`_ to aid preparation and automatic updates of API documentation when the code changes. The above piece of code renders in Sphinx like below:
|
||||
|
||||
.. image:: _static/doc-code-documentation-rendered.png
|
||||
:align: center
|
||||
:alt: Sample inline code after rendering
|
||||
|
||||
|
||||
Go for it!
|
||||
----------
|
||||
|
||||
When writing code for this repository, please follow guidelines below.
|
||||
|
||||
1. Document all building blocks of code: functions, structs, typedefs, enums, macros, etc. Provide enough information on purpose, functionality and limitations of documented items, as you would like to see them documented when reading the code by others.
|
||||
|
||||
2. Documentation of function should describe what this function does. If it accepts input parameters and returns some value, all of them should be explained.
|
||||
|
||||
3. Do not add a data type before parameter or any other characters besides spaces. All spaces and line breaks are compressed into a single space. If you like to break a line, then break it twice.
|
||||
|
||||
.. image:: _static/doc-code-function.png
|
||||
:align: center
|
||||
:alt: Sample function documented inline and after rendering
|
||||
|
||||
4. If function has void input or does not return any value, then skip ``@param`` or ``@return``
|
||||
|
||||
.. image:: _static/doc-code-void-function.png
|
||||
:align: center
|
||||
:alt: Sample void function documented inline and after rendering
|
||||
|
||||
5. When documenting members of a ``struct``, ``typedef`` or ``enum``, place specific comment like below after each member.
|
||||
|
||||
.. image:: _static/doc-code-member.png
|
||||
:align: center
|
||||
:alt: Sample of member documentation inline and after rendering
|
||||
|
||||
6. To provide well formatted lists, break the line after command (like ``@return`` in example below).
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if erase operation was successful
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_READ_ONLY if handle was opened as read only
|
||||
* - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist
|
||||
* - other error codes from the underlying storage driver
|
||||
*
|
||||
...
|
||||
|
||||
|
||||
7. Overview of functionality of documented header file, or group of files that make a library, should be placed in separate ``README.rst`` file.
|
||||
|
||||
Go one extra mile
|
||||
-----------------
|
||||
|
||||
There are couple of tips how you can make your documentation even better and more useful to the reader.
|
||||
|
||||
Add code snippets to illustrate implementation. To do so, enclose the snippet using ``@code{c}`` and ``@endcode`` commands.
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
*
|
||||
* @code{c}
|
||||
* // Example of using nvs_get_i32:
|
||||
* int32_t max_buffer_size = 4096; // default value
|
||||
* esp_err_t err = nvs_get_i32(my_handle, "max_buffer_size", &max_buffer_size);
|
||||
* assert(err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND);
|
||||
* // if ESP_ERR_NVS_NOT_FOUND was returned, max_buffer_size will still
|
||||
* // have its default value.
|
||||
* @endcode
|
||||
*
|
||||
...
|
||||
|
||||
To highlight some information use command ``@attention`` or ``@note``. Example below also shows how to use a numbered list.
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
*
|
||||
* @attention
|
||||
* 1. This API only impact WIFI_MODE_STA or WIFI_MODE_APSTA mode
|
||||
* 2. If the ESP32 is connected to an AP, call esp_wifi_disconnect to disconnect.
|
||||
*
|
||||
...
|
||||
|
||||
|
||||
Use markdown to make your documentation even more readable. With markdown you can add headers, links, tables and more.
|
||||
|
||||
::
|
||||
|
||||
...
|
||||
*
|
||||
* [ESP32 Technical Reference](http://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf)
|
||||
*
|
||||
...
|
||||
|
||||
Wrap up
|
||||
-------
|
||||
|
||||
We love good code that is doing cool things.
|
||||
We love it even better, if it is well documented, so we can quickly make it run and also do the cool things.
|
||||
|
@@ -1,3 +1,6 @@
|
||||
Build and Flash with Eclipse IDE
|
||||
********************************
|
||||
|
||||
Installing Eclipse IDE
|
||||
======================
|
||||
|
||||
|
78
docs/index.rst
Normal file
78
docs/index.rst
Normal file
@@ -0,0 +1,78 @@
|
||||
ESP32 Programming Guide
|
||||
=======================
|
||||
|
||||
.. caution::
|
||||
|
||||
Until ESP-IDF release 1.0, this documentation is a draft. It is incomplete and may have mistakes. Please mind your step!
|
||||
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:caption: Setup Toolchain
|
||||
:maxdepth: 1
|
||||
|
||||
Windows <windows-setup>
|
||||
Linux <linux-setup>
|
||||
Mac OS <macos-setup>
|
||||
|
||||
.. Configure - TBA
|
||||
|
||||
.. Connect - TBA
|
||||
|
||||
.. toctree::
|
||||
:caption: Build and Flash
|
||||
:maxdepth: 1
|
||||
|
||||
Make <make-project>
|
||||
Eclipse IDE <eclipse-setup>
|
||||
|
||||
.. toctree::
|
||||
:caption: What Else?
|
||||
:maxdepth: 1
|
||||
|
||||
partition-tables
|
||||
build_system
|
||||
openocd
|
||||
|
||||
.. toctree::
|
||||
:caption: API Reference
|
||||
:maxdepth: 1
|
||||
|
||||
Wi-Fi <api/esp_wifi>
|
||||
Bluetooth <api/bt>
|
||||
GPIO <api/gpio>
|
||||
Logging <api/log>
|
||||
Non-volatile storage <api/nvs>
|
||||
Virtual filesystem <api/vfs>
|
||||
Template <api/template>
|
||||
|
||||
.. toctree::
|
||||
:caption: Technical Reference
|
||||
|
||||
Technical Reference <http://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf>
|
||||
|
||||
.. Resources - TBA
|
||||
|
||||
.. toctree::
|
||||
:caption: Contribute
|
||||
:maxdepth: 1
|
||||
|
||||
contributing
|
||||
documenting-code
|
||||
contributor-agreement
|
||||
|
||||
.. toctree::
|
||||
:caption: Legal
|
||||
:maxdepth: 1
|
||||
|
||||
COPYRIGHT
|
||||
|
||||
.. About - TBA
|
||||
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
@@ -1,3 +1,6 @@
|
||||
Set up of Toolchain for Linux
|
||||
*****************************
|
||||
|
||||
Step 0: Prerequisites
|
||||
=====================
|
||||
|
||||
|
@@ -1,3 +1,6 @@
|
||||
Set up of Toolchain for Mac OS
|
||||
******************************
|
||||
|
||||
Step 0: Prerequisites
|
||||
=====================
|
||||
|
||||
|
63
docs/make-project.rst
Normal file
63
docs/make-project.rst
Normal file
@@ -0,0 +1,63 @@
|
||||
Build and Flash with Make
|
||||
=========================
|
||||
|
||||
Finding a project
|
||||
-----------------
|
||||
|
||||
As well as the `esp-idf-template <https://github.com/espressif/esp-idf-template>`_ project mentioned in the setup guide, esp-idf comes with some example projects on github in the `examples <https://github.com/espressif/esp-idf/tree/master/examples>`_ directory.
|
||||
|
||||
Once you've found the project you want to work with, change to its directory and you can configure and build it:
|
||||
|
||||
Configuring your project
|
||||
------------------------
|
||||
|
||||
`make menuconfig`
|
||||
|
||||
Compiling your project
|
||||
----------------------
|
||||
|
||||
`make all`
|
||||
|
||||
... will compile app, bootloader and generate a partition table based on the config.
|
||||
|
||||
Flashing your project
|
||||
---------------------
|
||||
|
||||
When `make all` finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this from make by running:
|
||||
|
||||
`make flash`
|
||||
|
||||
This will flash the entire project (app, bootloader and partition table) to a new chip. The settings for serial port flashing can be configured with `make menuconfig`.
|
||||
|
||||
You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it.
|
||||
|
||||
Compiling & Flashing Just the App
|
||||
---------------------------------
|
||||
|
||||
After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table:
|
||||
|
||||
* `make app` - build just the app.
|
||||
* `make app-flash` - flash just the app.
|
||||
|
||||
`make app-flash` will automatically rebuild the app if it needs it.
|
||||
|
||||
(There's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
|
||||
|
||||
The Partition Table
|
||||
-------------------
|
||||
|
||||
Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader.
|
||||
|
||||
A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x4000 in the flash.
|
||||
|
||||
Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.
|
||||
|
||||
The simplest way to use the partition table is to `make menuconfig` and choose one of the simple predefined partition tables:
|
||||
|
||||
* "Single factory app, no OTA"
|
||||
* "Factory app, two OTA definitions"
|
||||
|
||||
In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
|
||||
|
||||
For more details about :doc:`partition tables <partition-tables>` and how to create custom variations, view the :doc:`documentation <partition-tables>`.
|
||||
|
@@ -1,11 +1,14 @@
|
||||
Debugging
|
||||
=========
|
||||
|
||||
OpenOCD setup for ESP32
|
||||
-----------------------
|
||||
|
||||
The ESP31 and ESP32 have two powerful Xtensa cores, allowing for a great deal of variety of program architectures. The FreeRTOS
|
||||
OS that comes with ESP-IDF is capable multi-core pre-emptive multithreading, allowing for an intuitive way of writing software.
|
||||
The ESP31 and ESP32 have two powerful Xtensa cores, allowing for a great variety of program architectures. The FreeRTOS
|
||||
OS that comes with ESP-IDF is capable of multi-core pre-emptive multithreading, allowing for an intuitive way of writing software.
|
||||
|
||||
The downside of the ease of programming is that debugging without the right tools is harder: figuring out a bug that is caused
|
||||
by two threads, maybe even running simultaneously on two different CPU cures, can take a long time when all you have are printf
|
||||
by two threads, maybe even running simultaneously on two different CPU cores, can take a long time when all you have are printf
|
||||
statements. A better and in many cases quicker way to debug such problems is by using a debugger, connected to the processors over
|
||||
a debug port.
|
||||
|
||||
@@ -84,7 +87,7 @@ Connecting a debugger to OpenOCD
|
||||
OpenOCD should now be ready to accept gdb connections. If you have compiled the ESP32 toolchain using Crosstool-NG, or
|
||||
if you have downloaded a precompiled toolchain from the Espressif website, you should already have xtensa-esp32-elf-gdb,
|
||||
a version of gdb that can be used for this. First, make sure the project you want to debug is compiled and flashed
|
||||
into the ESP32s SPI flash. Then, in a different console than OpenOCD is running in, invoke gdb. For example, for the
|
||||
into the ESP32's SPI flash. Then, in a different console than OpenOCD is running in, invoke gdb. For example, for the
|
||||
template app, you would do this like such::
|
||||
|
||||
cd esp-idf-template
|
||||
|
@@ -1,5 +1,8 @@
|
||||
Partition Tables
|
||||
----------------
|
||||
================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x4000 in the flash.
|
||||
|
||||
|
6
docs/requirements.txt
Normal file
6
docs/requirements.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
# This is a list of python packages used to generate documentation. This file is used with pip:
|
||||
# pip install requirements.txt
|
||||
#
|
||||
sphinx
|
||||
sphinx-rtd-theme
|
||||
breathe
|
@@ -1,5 +1,8 @@
|
||||
Step 1: Toolchain for Windows: Quick Steps
|
||||
==================================
|
||||
Set up of Toolchain for Windows
|
||||
*******************************
|
||||
|
||||
Step 1: Quick Steps
|
||||
===================
|
||||
|
||||
Windows doesn't have a built-in "make" environment, so as well as installing the toolchain you will need a GNU-compatible environment. We use the MSYS2_ environment to provide.
|
||||
You don't need to use this environment all the time (you can use Eclipse_ or some other front-end), but it runs behind the scenes.
|
||||
|
9
examples/06_sntp/Makefile
Normal file
9
examples/06_sntp/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := sntp
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
41
examples/06_sntp/README.md
Normal file
41
examples/06_sntp/README.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Example: using LwIP SNTP module and time functions
|
||||
|
||||
This example demonstrates the use of LwIP SNTP module to obtain time from Internet servers. See the README.md file in the upper level 'examples' directory for more information about examples.
|
||||
|
||||
## Obtaining time using LwIP SNTP module
|
||||
|
||||
When this example boots first time after ESP32 is reset, it connects to WiFi and obtains time using SNTP.
|
||||
See `initialize_sntp` function for details.
|
||||
|
||||
## Timekeeping
|
||||
|
||||
Once time is synchronized, ESP32 will perform timekeeping using built-in timers.
|
||||
|
||||
- RTC clock is used to maintain accurate time when chip is in deep sleep mode
|
||||
|
||||
- FRC1 timer is used to provide time at microsecond accuracy when ESP32 is running.
|
||||
|
||||
Timekeeping using RTC timer is demonstrated in this example by going into deep sleep mode. After wake up, ESP32 will print current time without connecting to WiFi.
|
||||
|
||||
To use this functionality, make sure "Timers used for gettimeofday function" option in "ESP32-specific config" menu of menuconfig is set to "RTC and FRC1" or "RTC".
|
||||
|
||||
## Working with time
|
||||
|
||||
To get current time, [`gettimeofday`](http://man7.org/linux/man-pages/man2/gettimeofday.2.html) function may be used. Additionally the following [standard C library functions](http://en.cppreference.com/w/cpp/header/ctime) can be used to obtain time and manipulate it:
|
||||
|
||||
gettimeofday
|
||||
time
|
||||
asctime
|
||||
clock
|
||||
ctime
|
||||
difftime
|
||||
gmtime
|
||||
localtime
|
||||
mktime
|
||||
strftime
|
||||
|
||||
To set time, [`settimeofday`](http://man7.org/linux/man-pages/man2/settimeofday.2.html) POSIX function can be used. It is used internally in LwIP SNTP library to set current time when response from NTP server is received.
|
||||
|
||||
## Timezones
|
||||
|
||||
To set local timezone, use [`setenv`](http://man7.org/linux/man-pages/man3/setenv.3.html) and [`tzset`](http://man7.org/linux/man-pages/man3/tzset.3.html) POSIX functions. First, call `setenv` to set `TZ` environment variable to the correct value depending on device location. Format of the time string is described in [libc documentation](https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html). Next, call `tzset` to update C library runtime data for the new time zone. Once these steps are done, `localtime` function will return correct local time, taking time zone offset and daylight saving time into account.
|
17
examples/06_sntp/main/Kconfig.projbuild
Normal file
17
examples/06_sntp/main/Kconfig.projbuild
Normal file
@@ -0,0 +1,17 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config WIFI_SSID
|
||||
string "WiFi SSID"
|
||||
default "myssid"
|
||||
help
|
||||
SSID (network name) for the example to connect to.
|
||||
|
||||
config WIFI_PASSWORD
|
||||
string "WiFi Password"
|
||||
default "myssid"
|
||||
help
|
||||
WiFi password (WPA or WPA2) for the example to use.
|
||||
|
||||
Can be left blank if the network has no security set.
|
||||
|
||||
endmenu
|
10
examples/06_sntp/main/component.mk
Normal file
10
examples/06_sntp/main/component.mk
Normal file
@@ -0,0 +1,10 @@
|
||||
#
|
||||
# Main Makefile. This is basically the same as a component makefile.
|
||||
#
|
||||
# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default,
|
||||
# this will take the sources in the src/ directory, compile them and link them into
|
||||
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
|
||||
# please read the ESP-IDF documents if you need to do this.
|
||||
#
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
163
examples/06_sntp/main/sntp_main.c
Normal file
163
examples/06_sntp/main/sntp_main.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/* LwIP SNTP example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event_loop.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_deepsleep.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "apps/sntp/sntp.h"
|
||||
|
||||
/* The examples use simple WiFi configuration that you can set via
|
||||
'make menuconfig'.
|
||||
|
||||
If you'd rather not, just change the below entries to strings with
|
||||
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
|
||||
*/
|
||||
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
|
||||
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
|
||||
|
||||
/* FreeRTOS event group to signal when we are connected & ready to make a request */
|
||||
static EventGroupHandle_t wifi_event_group;
|
||||
|
||||
/* The event group allows multiple bits for each event,
|
||||
but we only care about one event - are we connected
|
||||
to the AP with an IP? */
|
||||
const int CONNECTED_BIT = BIT0;
|
||||
|
||||
static const char *TAG = "example";
|
||||
|
||||
/* Variable holding number of times ESP32 restarted since first boot.
|
||||
* It is placed into RTC memory using RTC_DATA_ATTR and
|
||||
* maintains its value when ESP32 wakes from deep sleep.
|
||||
*/
|
||||
RTC_DATA_ATTR static int boot_count = 0;
|
||||
|
||||
static void obtain_time(void);
|
||||
static void initialize_sntp(void);
|
||||
static void initialise_wifi(void);
|
||||
static esp_err_t event_handler(void *ctx, system_event_t *event);
|
||||
|
||||
|
||||
void app_main()
|
||||
{
|
||||
++boot_count;
|
||||
ESP_LOGI(TAG, "Boot count: %d", boot_count);
|
||||
|
||||
time_t now;
|
||||
struct tm timeinfo;
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
// Is time set? If not, tm_year will be (1970 - 1900).
|
||||
if (timeinfo.tm_year < (2016 - 1900)) {
|
||||
ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
|
||||
obtain_time();
|
||||
// update 'now' variable with current time
|
||||
time(&now);
|
||||
}
|
||||
char strftime_buf[64];
|
||||
|
||||
// Set timezone to Eastern Standard Time and print local time
|
||||
setenv("TZ", "EST5EDT,M3.2.0/2,M11.1.0", 1);
|
||||
tzset();
|
||||
localtime_r(&now, &timeinfo);
|
||||
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
|
||||
ESP_LOGI(TAG, "The current date/time in New York is: %s", strftime_buf);
|
||||
|
||||
// Set timezone to China Standard Time
|
||||
setenv("TZ", "CST-8CDT-9,M4.2.0/2,M9.2.0/3", 1);
|
||||
tzset();
|
||||
localtime_r(&now, &timeinfo);
|
||||
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
|
||||
ESP_LOGI(TAG, "The current date/time in Shanghai is: %s", strftime_buf);
|
||||
|
||||
const int deep_sleep_sec = 10;
|
||||
ESP_LOGI(TAG, "Entering deep sleep for %d seconds", deep_sleep_sec);
|
||||
system_deep_sleep(1000000LL * deep_sleep_sec);
|
||||
}
|
||||
|
||||
static void obtain_time(void)
|
||||
{
|
||||
nvs_flash_init();
|
||||
system_init();
|
||||
initialise_wifi();
|
||||
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT,
|
||||
false, true, portMAX_DELAY);
|
||||
initialize_sntp();
|
||||
|
||||
// wait for time to be set
|
||||
time_t now = 0;
|
||||
struct tm timeinfo = { 0 };
|
||||
int retry = 0;
|
||||
const int retry_count = 10;
|
||||
while(timeinfo.tm_year < (2016 - 1900) && ++retry < retry_count) {
|
||||
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
time(&now);
|
||||
localtime_r(&now, &timeinfo);
|
||||
}
|
||||
}
|
||||
|
||||
static void initialize_sntp(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Initializing SNTP");
|
||||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
sntp_setservername(0, "pool.ntp.org");
|
||||
sntp_init();
|
||||
}
|
||||
|
||||
static void initialise_wifi(void)
|
||||
{
|
||||
tcpip_adapter_init();
|
||||
wifi_event_group = xEventGroupCreate();
|
||||
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
|
||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
|
||||
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
|
||||
wifi_config_t wifi_config = {
|
||||
.sta = {
|
||||
.ssid = EXAMPLE_WIFI_SSID,
|
||||
.password = EXAMPLE_WIFI_PASS,
|
||||
},
|
||||
};
|
||||
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
|
||||
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
|
||||
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
|
||||
ESP_ERROR_CHECK( esp_wifi_start() );
|
||||
}
|
||||
|
||||
static esp_err_t event_handler(void *ctx, system_event_t *event)
|
||||
{
|
||||
switch(event->event_id) {
|
||||
case SYSTEM_EVENT_STA_START:
|
||||
esp_wifi_connect();
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||
/* This is a workaround as ESP32 WiFi libs don't currently
|
||||
auto-reassociate. */
|
||||
esp_wifi_connect();
|
||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
Reference in New Issue
Block a user