rel_1.6.0 init

This commit is contained in:
guocheng.kgc 2020-06-18 20:06:52 +08:00 committed by shengdong.dsd
commit 27b3e2883d
19359 changed files with 8093121 additions and 0 deletions

74
.gitignore vendored Executable file
View file

@ -0,0 +1,74 @@
#framework/protocol/linkkit/sdk/iotx-sdk-c_clone
out
prebuild/*
Living_SDK/diff.txt
Living_SDK/trace_test
Living_SDK/activate
Living_SDK/out
Living_SDK/*.out
Living_SDK/*.db
Living_SDK/.gdbinit
Living_SDK/.gdbinitkernel
Living_SDK/.gdbinitframework
Living_SDK/.gdbinitapp
Living_SDK/.openocd_cfg
Living_SDK/copy_bootloader_output_for_eclipse
Living_SDK/copy_output_for_eclipse
Living_SDK/*.sw*
Living_SDK/build/compiler
Living_SDK/build/OpenOCD
Living_SDK/si
Living_SDK/.cproject
Living_SDK/.project
Living_SDK/*.pyc
Living_SDK/aos_partition_*.bin
Living_SDK/OSX
Living_SDK/example/flash/flash.mk
Living_SDK/example/flash/main.c
Living_SDK/example/flash/README.md
Living_SDK/settings.json
Living_SDK/build/cmd/win32/Python27/Lib/encodings/*.pyc
Living_SDK/*.d
Living_SDK/build/scripts/config_mk.py
Living_SDK/build/scripts/*.pyc
Living_SDK/$Recycle.Bin
Living_SDK/.sconsign.dblite
Living_SDK/ckhobbit*.map
Living_SDK/projects/autogen/*
Living_SDK/framework/protocol/linkkit/sdk/iotx-sdk-c_clone/ENV_VARS.tmp
Living_SDK/framework/protocol/linkkit/sdk/iotx-sdk-c_clone/objlist.tmp
Living_SDK/framework/protocol/linkkit/sdk/iotx-sdk-c_clone/make.settings
# source sight project files
Living_SDK/*.IAB
Living_SDK/*.IAD
Living_SDK/*.IMB
Living_SDK/*.IMD
Living_SDK/*.PFI
Living_SDK/*.PO
Living_SDK/*.PR
Living_SDK/*.PRI
Living_SDK/*.PS
Living_SDK/*.SearchResults
Living_SDK/*.WK3
Living_SDK/GPATH
Living_SDK/GRTAGS
Living_SDK/GTAGS
Living_SDK/tags
# MAC OS
.DS_Store
._.DS_Store
# BSP
Living_SDK/platform/mcu/rtl8710bn/Debug
Living_SDK/example/smart_led_strip
Living_SDK/example/smart_led_bulb
Living_SDK/example/smart_outlet
Living_SDK/example/smart_outlet_meter
Living_SDK/example/living_platform
Living_SDK/example/comboapp
.gdbinit
cscope.in.out
cscope.out
cscope.po.out
tags
*.mk_old
.vscode

7
.gitmodules vendored Normal file
View file

@ -0,0 +1,7 @@
[submodule "Products/Smart_lighting/smart_led_bulb"]
path = Products/Smart_lighting/smart_led_bulb
url = git@code.aliyun.com:living_platform/smart_led_bulb.git
branch = slb_1.6.0
[submodule "Products/Smart_outlet/smart_outlet_meter"]
path = Products/Smart_outlet/smart_outlet_meter
url = git@code.aliyun.com:living_platform/smart_outlet_with_meter.git

201
LICENSE Normal file
View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.

57
Living_SDK/.gitignore vendored Executable file
View file

@ -0,0 +1,57 @@
#framework/protocol/linkkit/sdk/iotx-sdk-c_clone
trace_test
activate
out
*.out
*.db
.gdbinit
.gdbinitkernel
.gdbinitframework
.gdbinitapp
.openocd_cfg
copy_bootloader_output_for_eclipse
copy_output_for_eclipse
*.sw*
build/compiler
build/OpenOCD
si
.cproject
.project
*.pyc
aos_partition_*.bin
OSX
example/flash/flash.mk
example/flash/main.c
example/flash/README.md
settings.json
build/cmd/win32/Python27/Lib/encodings/*.pyc
*.d
build/scripts/config_mk.py
build/scripts/*.pyc
$Recycle.Bin
.sconsign.dblite
ckhobbit*.map
projects/autogen/*
framework/protocol/linkkit/sdk/iotx-sdk-c_clone/ENV_VARS.tmp
framework/protocol/linkkit/sdk/iotx-sdk-c_clone/objlist.tmp
framework/protocol/linkkit/sdk/iotx-sdk-c_clone/make.settings
# source sight project files
*.IAB
*.IAD
*.IMB
*.IMD
*.PFI
*.PO
*.PR
*.PRI
*.PS
*.SearchResults
*.WK3
GPATH
GRTAGS
GTAGS
tags
# MAC OS
.DS_Store
# BSP
platform/mcu/rtl8710bn/Debug/

View file

@ -0,0 +1 @@
This software component is used to help users port third-party programs, but WITHOUT ANY WARRANTY. The entire risk as to the quality and performance of the program is with you. Should the program prove defective, you assume the cost of all necessary servicing, repair or correction. The use of third-party programs must also follow its own permissive license.

View file

@ -0,0 +1,759 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include "k_api.h"
#include "ramfs.h"
#define LL_NODE_META_SIZE (sizeof(ll_node_t*) + sizeof(ll_node_t*))
#define LL_PREV_P_OFFSET(ll_p) (ll_p->n_size)
#define LL_NEXT_P_OFFSET(ll_p) (ll_p->n_size + sizeof(ll_node_t*))
static ramfs_ent_t* ramfs_ent_get(const char * fn);
static ramfs_ent_t* ramfs_ent_new(const char * fn);
static void * ll_ins_head(ll_t * ll_p);
static void ll_rem(ll_t * ll_p, void * node_p);
static void * ll_get_head(ll_t * ll_p);
static void * ll_get_tail(ll_t * ll_p);
static void * ll_get_next(ll_t * ll_p, void * n_act);
static void * ll_get_prev(ll_t * ll_p, void * n_act);
static void node_set_prev(ll_t * ll_p, ll_node_t* act, ll_node_t* prev);
static void node_set_next(ll_t * ll_p, ll_node_t* act, ll_node_t* next);
static void node_set_prev(ll_t * ll_p, ll_node_t* act, ll_node_t* prev);
static void node_set_next(ll_t * ll_p, ll_node_t* act, ll_node_t* next);
static void ll_init(ll_t * ll_p, uint32_t n_size);
static ll_t file_ll;
static bool inited = false;
/**
* Create a driver for ufs and initialize it.
*/
void ramfs_init(void)
{
ll_init(&file_ll, sizeof(ramfs_ent_t));
inited = true;
}
/**
* Give the state of the ufs
* @return true if ufs is initialized and can be used else false
*/
bool ramfs_ready(void)
{
return inited;
}
/**
* Open a file in ufs
* @param file_p pointer to a ramfs_file_t variable
* @param fn name of the file. There are no directories so e.g. "myfile.txt"
* @param mode element of 'fs_mode_t' enum or its 'OR' connection (e.g. FS_MODE_WR | FS_MODE_RD)
* @return RAMFS_RES_OK: no error, the file is opened
* any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_open (void * file_p, const char * fn, ramfs_mode_t mode)
{
ramfs_file_t * fp = file_p; /*Convert type*/
ramfs_ent_t* ent = ramfs_ent_get(fn);
fp->ent = NULL;
/*If the file not exists ...*/
if( ent == NULL) {
if((mode & RAMFS_MODE_WR) != 0) { /*Create the file if opened for write*/
ent = ramfs_ent_new(fn);
if(ent == NULL) return RAMFS_RES_FULL; /*No space for the new file*/
} else {
return RAMFS_RES_NOT_EX; /*Can not read not existing file*/
}
}
/*Can not write already opened and const data files*/
if((mode & RAMFS_MODE_WR) != 0) {
if(ent->oc != 0) return RAMFS_RES_LOCKED;
if(ent->const_data != 0) return RAMFS_RES_DENIED;
}
/*No error, the file can be opened*/
fp->ent = ent;
fp->ent->ar = mode & RAMFS_MODE_RD ? 1 : 0;
fp->ent->aw = mode & RAMFS_MODE_WR ? 1 : 0;
fp->rwp = 0;
ent->oc ++;
return RAMFS_RES_OK;
}
/**
* Create a file with a constant data
* @param fn name of the file (directories are not supported)
* @param const_p pointer to a constant data
* @param len length of the data pointed by 'const_p' in bytes
* @return RAMFS_RES_OK: no error, the file is read
* any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_create_const(const char * fn, const void * const_p, uint32_t len)
{
ramfs_file_t file;
ramfs_res_t res;
/*Error if the file already exists*/
res = ramfs_open(&file, fn, RAMFS_MODE_RD);
if(res == RAMFS_RES_OK) {
ramfs_close(&file);
return RAMFS_RES_DENIED;
}
ramfs_close(&file);
res = ramfs_open(&file, fn, RAMFS_MODE_WR);
if(res != RAMFS_RES_OK) return res;
ramfs_ent_t* ent = file.ent;
if(ent->data_d != NULL) return RAMFS_RES_DENIED;
ent->data_d = (void *) const_p;
ent->size = len;
ent->const_data = 1;
res = ramfs_close(&file);
if(res != RAMFS_RES_OK) return res;
return RAMFS_RES_OK;
}
/**
* Close an opened file
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open)
* @return RAMFS_RES_OK: no error, the file is read
* any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_close (void * file_p)
{
ramfs_file_t * fp = file_p; /*Convert type*/
if(fp->ent == NULL) return RAMFS_RES_OK;
/*Decrement the Open counter*/
if(fp->ent->oc > 0) {
fp->ent->oc--;
}
return RAMFS_RES_OK;
}
/**
* Remove a file. The file can not be opened.
* @param fn '\0' terminated string
* @return RAMFS_RES_OK: no error, the file is removed
* RAMFS_RES_DENIED: the file was opened, remove failed
*/
ramfs_res_t ramfs_remove(const char * fn)
{
ramfs_ent_t* ent = ramfs_ent_get(fn);
/*Can not be deleted is opened*/
if(ent->oc != 0) return RAMFS_RES_DENIED;
ll_rem(&file_ll, ent);
krhino_mm_free(ent->fn_d);
ent->fn_d = NULL;
if(ent->const_data == 0){
krhino_mm_free(ent->data_d);
ent->data_d = NULL;
}
krhino_mm_free(ent);
return RAMFS_RES_OK;
}
/**
* Read data from an opened file
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open )
* @param buf pointer to a memory block where to store the read data
* @param btr number of Bytes To Read
* @param br the real number of read bytes (Byte Read)
* @return RAMFS_RES_OK: no error, the file is read
* any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_read (void * file_p, void * buf, uint32_t btr, uint32_t * br)
{
ramfs_file_t * fp = file_p; /*Convert type*/
ramfs_ent_t* ent = fp->ent;
*br = 0;
if(ent->data_d == NULL || ent->size == 0) { /*Don't read empty files*/
return RAMFS_RES_OK;
} else if(fp->ent->ar == 0) { /*The file is not opened for read*/
return RAMFS_RES_DENIED;
}
/*No error, read the file*/
if(fp->rwp + btr > ent->size) { /*Check too much bytes read*/
*br = ent->size - fp->rwp;
} else {
*br = btr;
}
/*Read the data*/
uint8_t * data8_p;
if(ent->const_data == 0) {
data8_p = (uint8_t*) ent->data_d;
} else {
data8_p = ent->data_d;
}
data8_p += fp->rwp;
memcpy(buf, data8_p, *br);
fp->rwp += *br; /*Refresh the read write pointer*/
return RAMFS_RES_OK;
}
/**
* Write data to an opened file
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open)
* @param buf pointer to a memory block which content will be written
* @param btw the number Bytes To Write
* @param bw The real number of written bytes (Byte Written)
* @return RAMFS_RES_OK: no error, the file is read
* any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_write (void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
{
ramfs_file_t * fp = file_p; /*Convert type*/
*bw = 0;
if(fp->ent->aw == 0) return RAMFS_RES_DENIED; /*Not opened for write*/
ramfs_ent_t* ent = fp->ent;
/*Reallocate data array if it necessary*/
uint32_t new_size = fp->rwp + btw;
if(new_size > ent->size) {
uint8_t* new_data = krhino_mm_realloc(ent->data_d, new_size);
if(new_data == NULL) return RAMFS_RES_FULL; /*Cannot allocate the new memory*/
ent->data_d = new_data;
ent->size = new_size;
}
/*Write the file*/
uint8_t * data8_p = (uint8_t*) ent->data_d;
data8_p += fp->rwp;
memcpy(data8_p, buf, btw);
*bw = btw;
fp->rwp += *bw;
return RAMFS_RES_OK;
}
/**
* Set the read write pointer. Also expand the file size if necessary.
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open )
* @param pos the new position of read write pointer
* @return RAMFS_RES_OK: no error, the file is read
* any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_seek (void * file_p, uint32_t pos)
{
ramfs_file_t * fp = file_p; /*Convert type*/
ramfs_ent_t* ent = fp->ent;
/*Simply move the rwp before EOF*/
if(pos < ent->size) {
fp->rwp = pos;
} else { /*Expand the file size*/
if(fp->ent->aw == 0) return RAMFS_RES_DENIED; /*Not opened for write*/
uint8_t* new_data = krhino_mm_realloc(ent->data_d, pos);
if(new_data == NULL) return RAMFS_RES_FULL; /*Out of memory*/
ent->data_d = new_data;
ent->size = pos;
fp->rwp = pos;
}
return RAMFS_RES_OK;
}
/**
* Give the position of the read write pointer
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open )
* @param pos_p pointer to to store the result
* @return RAMFS_RES_OK: no error, the file is read
* any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_tell (void * file_p, uint32_t * pos_p)
{
ramfs_file_t * fp = file_p; /*Convert type*/
*pos_p = fp->rwp;
return RAMFS_RES_OK;
}
/**
* Truncate the file size to the current position of the read write pointer
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open )
* @return RAMFS_RES_OK: no error, the file is read
* any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_trunc (void * file_p)
{
ramfs_file_t * fp = file_p; /*Convert type*/
ramfs_ent_t* ent = fp->ent;
if(fp->ent->aw == 0) return RAMFS_RES_DENIED; /*Not opened for write*/
void * new_data = krhino_mm_realloc(ent->data_d, fp->rwp);
if(new_data == NULL) return RAMFS_RES_FULL; /*Out of memory*/
ent->data_d = new_data;
ent->size = fp->rwp;
return RAMFS_RES_OK;
}
/**
* Give the size of the file in bytes
* @param file_p file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open )
* @param size_p pointer to store the size
* @return RAMFS_RES_OK: no error, the file is read
* any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_size (void * file_p, uint32_t * size_p)
{
ramfs_file_t * fp = file_p; /*Convert type*/
ramfs_ent_t* ent = fp->ent;
*size_p = ent->size;
return RAMFS_RES_OK;
}
/**
* get access info
* @param path uFS doesn't support folders so it has to be ""
* @param mode the info to get
* @return RAMFS_RES_OK or any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_access(const char * path, int mode)
{
ramfs_ent_t* ent = ramfs_ent_get(path);
/*If the file not exists ...*/
if( ent == NULL) {
return RAMFS_RES_DENIED; /*Can not read not existing file*/
} else if((mode & F_OK ) != 0){
return RAMFS_RES_OK;
}
/*Can not write already opened and const data files*/
if((mode & R_OK ) != 0) {
if(ent->ar == 0) {
return RAMFS_RES_DENIED;
} else {
return RAMFS_RES_OK;
}
}
if((mode & W_OK) != 0) {
if(ent->aw == 0) {
return RAMFS_RES_DENIED;
} else {
return RAMFS_RES_OK;
}
}
return RAMFS_RES_OK;
}
/**
* Create a directory
* @param path the path of file
* @return RAMFS_RES_OK or any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_mkdir(const char * path)
{
return RAMFS_RES_OK;
}
/**
* Initialize a ramfs_read_dir_t variable to directory reading
* @param rddir_p pointer to a 'ramfs_dir_t' variable
* @param path the path of file
* @return RAMFS_RES_OK or any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_dir_open(void * rddir_p, const char * path)
{
ramfs_dir_t * ramfs_rddir_p = rddir_p;
ramfs_rddir_p->last_ent = NULL;
return RAMFS_RES_OK;
}
/**
* Read the next file name
* @param dir_p pointer to an initialized 'ramfs_dir_t' variable
* @param fn pointer to buffer to sore the file name
* @return RAMFS_RES_OK or any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_dir_read(void * dir_p, char * fn)
{
ramfs_dir_t * ufs_dir_p = dir_p;
if(ufs_dir_p->last_ent == NULL) {
ufs_dir_p->last_ent = ll_get_head(&file_ll);
} else {
ufs_dir_p->last_ent = ll_get_next(&file_ll, ufs_dir_p->last_ent);
}
if(ufs_dir_p->last_ent != NULL) {
strcpy(fn, ufs_dir_p->last_ent->fn_d);
} else {
fn[0] = '\0';
}
return RAMFS_RES_OK;
}
/**
* Close the directory reading
* @param rddir_p pointer to an initialized 'ramfs_dir_t' variable
* @return RAMFS_RES_OK or any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_dir_close(void * rddir_p)
{
(void)rddir_p;
return RAMFS_RES_OK;
}
/**
* Give the size of a drive
* @param total_p pointer to store the total size [kB]
* @param free_p pointer to store the free site [kB]
* @return RAMFS_RES_OK or any error from 'ramfs_res_t'
*/
ramfs_res_t ramfs_free (uint32_t * total_p, uint32_t * free_p)
{
return RAMFS_RES_OK;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Gives the ramfs_entry from a filename
* @param fn filename ('\0' terminated string)
* @return pointer to the dynamically allocated entry with 'fn' filename.
* NULL if no entry found with that name.
*/
static ramfs_ent_t* ramfs_ent_get(const char * fn)
{
ramfs_ent_t* fp;
LL_READ(file_ll, fp) {
if(strcmp(fp->fn_d, fn) == 0) {
return fp;
}
}
return NULL;
}
/**
* Create a new entry with 'fn' filename
* @param fn filename ('\0' terminated string)
* @return pointer to the dynamically allocated new entry.
* NULL if no space for the entry.
*/
static ramfs_ent_t* ramfs_ent_new(const char * fn)
{
ramfs_ent_t* new_ent = NULL;
new_ent = ll_ins_head(&file_ll); /*Create a new file*/
if(new_ent == NULL) {
return NULL;
}
new_ent->fn_d = krhino_mm_alloc(strlen(fn) + 1); /*Save the name*/
strcpy(new_ent->fn_d, fn);
new_ent->data_d = NULL;
new_ent->size = 0;
new_ent->oc = 0;
new_ent->const_data = 0;
return new_ent;
}
/**
* Initialize linked list
* @param ll_dsc pointer to ll_dsc variable
* @param n_size the size of 1 node in bytes
*/
void ll_init(ll_t * ll_p, uint32_t n_size)
{
ll_p->head = NULL;
ll_p->tail = NULL;
if(n_size & 0x3) {
n_size &= ~0x3;
n_size += 4;
}
ll_p->n_size = n_size;
}
/**
* Add a new head to a linked list
* @param ll_p pointer to linked list
* @return pointer to the new head
*/
void * ll_ins_head(ll_t * ll_p)
{
ll_node_t* n_new;
n_new = krhino_mm_alloc(ll_p->n_size + LL_NODE_META_SIZE);
if(n_new != NULL) {
node_set_prev(ll_p, n_new, NULL); /*No prev. before the new head*/
node_set_next(ll_p, n_new, ll_p->head); /*After new comes the old head*/
if(ll_p->head != NULL) { /*If there is old head then before it goes the new*/
node_set_prev(ll_p, ll_p->head, n_new);
}
ll_p->head = n_new; /*Set the new head in the dsc.*/
if(ll_p->tail == NULL) {/*If there is no tail (1. node) set the tail too*/
ll_p->tail = n_new;
}
}
return n_new;
}
/**
* Add a new tail to a linked list
* @param ll_p pointer to linked list
* @return pointer to the new tail
*/
void * ll_ins_tail(ll_t * ll_p)
{
ll_node_t* n_new;
n_new = krhino_mm_alloc(ll_p->n_size + LL_NODE_META_SIZE);
if(n_new != NULL) {
node_set_next(ll_p, n_new, NULL); /*No next after the new tail*/
node_set_prev(ll_p, n_new, ll_p->tail); /*The prev. before new is tho old tail*/
if(ll_p->tail != NULL) { /*If there is old tail then the new comes after it*/
node_set_next(ll_p, ll_p->tail, n_new);
}
ll_p->tail = n_new; /*Set the new tail in the dsc.*/
if(ll_p->head == NULL) { /*If there is no head (1. node) set the head too*/
ll_p->head = n_new;
}
}
return n_new;
}
/**
* Remove the node 'node_p' from 'll_p' linked list.
* It Dose not free the the memory of node.
* @param ll_p pointer to the linked list of 'node_p'
* @param node_p pointer to node in 'll_p' linked list
*/
void ll_rem(ll_t * ll_p, void * node_p)
{
if(ll_get_head(ll_p) == node_p) {
/*The new head will be the node after 'n_act'*/
ll_p->head = ll_get_next(ll_p, node_p);
if(ll_p->head == NULL) {
ll_p->tail = NULL;
}
else {
node_set_prev(ll_p, ll_p->head, NULL);
}
}
else if(ll_get_tail(ll_p) == node_p) {
/*The new tail will be the node before 'n_act'*/
ll_p->tail = ll_get_prev(ll_p, node_p);
if(ll_p->tail == NULL) {
ll_p->head = NULL;
}
else {
node_set_next(ll_p, ll_p->tail, NULL);
}
}
else
{
ll_node_t* n_prev = ll_get_prev(ll_p, node_p);
ll_node_t* n_next = ll_get_next(ll_p, node_p);
node_set_next(ll_p, n_prev, n_next);
node_set_prev(ll_p, n_next, n_prev);
}
}
/**
* Remove and free all elements from a linked list. The list remain valid but become empty.
* @param ll_p pointer to linked list
*/
void ll_clear(ll_t * ll_p)
{
void * i;
void * i_next;
i = ll_get_head(ll_p);
i_next = NULL;
while(i != NULL) {
i_next = ll_get_next(ll_p, i);
ll_rem(ll_p, i);
krhino_mm_free(i);
i = i_next;
}
}
/**
* Move a node to a new linked list
* @param ll_ori_p pointer to the original (old) linked list
* @param ll_new_p pointer to the new linked list
* @param node pointer to a node
*/
void ll_chg_list(ll_t * ll_ori_p, ll_t * ll_new_p, void * node)
{
ll_rem(ll_ori_p, node);
/*Set node as head*/
node_set_prev(ll_new_p, node, NULL);
node_set_next(ll_new_p, node, ll_new_p->head);
if(ll_new_p->head != NULL) { /*If there is old head then before it goes the new*/
node_set_prev(ll_new_p, ll_new_p->head, node);
}
ll_new_p->head = node; /*Set the new head in the dsc.*/
if(ll_new_p->tail == NULL) { /*If there is no tail (first node) set the tail too*/
ll_new_p->tail = node;
}
}
/**
* Return with head node of the linked list
* @param ll_p pointer to linked list
* @return pointer to the head of 'll_p'
*/
void * ll_get_head(ll_t * ll_p)
{
void * head = NULL;
if(ll_p != NULL) {
head = ll_p->head;
}
return head;
}
/**
* Return with tail node of the linked list
* @param ll_p pointer to linked list
* @return pointer to the head of 'll_p'
*/
void * ll_get_tail(ll_t * ll_p)
{
void * tail = NULL;
if(ll_p != NULL) {
tail = ll_p->tail;
}
return tail;
}
/**
* Return with the pointer of the next node after 'n_act'
* @param ll_p pointer to linked list
* @param n_act pointer a node
* @return pointer to the next node
*/
void * ll_get_next(ll_t * ll_p, void * n_act)
{
void * next = NULL;
if(ll_p != NULL) {
ll_node_t* n_act_d = n_act;
memcpy(&next, n_act_d + LL_NEXT_P_OFFSET(ll_p), sizeof(void *));
}
return next;
}
/**
* Return with the pointer of the previous node after 'n_act'
* @param ll_p pointer to linked list
* @param n_act pointer a node
* @return pointer to the previous node
*/
void * ll_get_prev(ll_t * ll_p, void * n_act)
{
void * prev = NULL;
if(ll_p != NULL) {
ll_node_t* n_act_d = n_act;
memcpy(&prev, n_act_d + LL_PREV_P_OFFSET(ll_p), sizeof(void *));
}
return prev;
}
void ll_swap(ll_t * ll_p, void * n1_p, void * n2_p)
{
(void)(ll_p);
(void)(n1_p);
(void)(n2_p);
/*TODO*/
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Set the 'pervious node pointer' of a node
* @param ll_p pointer to linked list
* @param act pointer to a node which prev. node pointer should be set
* @param prev pointer to a node which should be the previous node before 'act'
*/
static void node_set_prev(ll_t * ll_p, ll_node_t* act, ll_node_t* prev)
{
memcpy(act + LL_PREV_P_OFFSET(ll_p), &prev, sizeof(ll_node_t*));
}
/**
* Set the 'next node pointer' of a node
* @param ll_p pointer to linked list
* @param act pointer to a node which next node pointer should be set
* @param next pointer to a node which should be the next node before 'act'
*/
static void node_set_next(ll_t * ll_p, ll_node_t* act, ll_node_t* next)
{
memcpy(act + LL_NEXT_P_OFFSET(ll_p), &next, sizeof(ll_node_t*));
}

View file

@ -0,0 +1,255 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef LV_UFS_H
#define LV_UFS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#define RAMFS_LETTER 'U'
#define R_OK 4 /* Test for read permission. */
#define W_OK 2 /* Test for write permission. */
#define X_OK 1 /* Test for execute permission. */
#define F_OK 0 /* Test for existence. */
#define LL_READ(list, i) for(i = ll_get_head(&list); i != NULL; i = ll_get_next(&list, i))
#define LL_READ_BACK(list, i) for(i = ll_get_tail(&list); i != NULL; i = ll_get_prev(&list, i))
/*Description of a file entry */
typedef struct
{
char * fn_d;
void * data_d;
uint32_t size; /*Data length in bytes*/
uint16_t oc; /*Open Count*/
uint8_t const_data :1;
uint8_t ar :1; /*1: Access for read is enabled */
uint8_t aw :1; /*1: Access for write is enabled */
}ramfs_ent_t;
/*File descriptor, used to handle opening an entry more times simultaneously
Contains unique informations about the specific opening*/
typedef struct
{
ramfs_ent_t* ent; /*Pointer to the entry*/
uint32_t rwp; /*Read Write Pointer*/
}ramfs_file_t;
/* Read directory descriptor.
* It is used to to iterate through the entries in a directory*/
typedef struct
{
ramfs_ent_t * last_ent;
}ramfs_dir_t;
typedef enum
{
RAMFS_RES_OK = 0,
RAMFS_RES_HW_ERR, /*Low level hardware error*/
RAMFS_RES_FS_ERR, /*Error in the file system structure */
RAMFS_RES_NOT_EX, /*Driver, file or directory is not exists*/
RAMFS_RES_FULL, /*Disk full*/
RAMFS_RES_LOCKED, /*The file is already opened*/
RAMFS_RES_DENIED, /*Access denied. Check 'fs_open' modes and write protect*/
RAMFS_RES_BUSY, /*The file system now can't handle it, try later*/
RAMFS_RES_TOUT, /*Process time outed*/
RAMFS_RES_NOT_IMP, /*Requested function is not implemented*/
RAMFS_RES_OUT_OF_MEM, /*Not enough memory for an internal operation*/
RAMFS_RES_INV_PARAM, /*Invalid parameter among arguments*/
RAMFS_RES_UNKNOWN, /*Other unknown error*/
}ramfs_res_t;
typedef enum
{
RAMFS_MODE_WR = 0x01,
RAMFS_MODE_RD = 0x02,
}ramfs_mode_t;
typedef struct
{
uint32_t total_size;
uint32_t free_cnt;
uint32_t free_size;
uint32_t free_biggest_size;
uint32_t used_cnt;
uint8_t used_pct;
uint8_t frag_pct;
}lv_mem_monitor_t;
/*Dummy type to make handling easier*/
typedef uint8_t ll_node_t;
/*Description of a linked list*/
typedef struct
{
uint32_t n_size;
ll_node_t* head;
ll_node_t* tail;
}ll_t;
/**
* Create a driver for ufs and initialize it.
*/
void ramfs_init(void);
/**
* Give the state of the ufs
* @return true if ufs is initialized and can be used else false
*/
bool ramfs_ready(void);
/**
* Open a file in ufs
* @param file_p pointer to a ramfs_file_t variable
* @param fn name of the file. There are no directories so e.g. "myfile.txt"
* @param mode element of 'fs_mode_t' enum or its 'OR' connection (e.g. FS_MODE_WR | FS_MODE_RD)
* @return RAMFS_RES_OK: no error, the file is opened
* any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_open (void * file_p, const char * fn, ramfs_mode_t mode);
/**
* Create a file with a constant data
* @param fn name of the file (directories are not supported)
* @param const_p pointer to a constant data
* @param len length of the data pointed by 'const_p' in bytes
* @return RAMFS_RES_OK: no error, the file is read
* any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_create_const(const char * fn, const void * const_p, uint32_t len);
/**
* Close an opened file
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open)
* @return RAMFS_RES_OK: no error, the file is read
* any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_close (void * file_p);
/**
* Remove a file. The file can not be opened.
* @param fn '\0' terminated string
* @return RAMFS_RES_OK: no error, the file is removed
* RAMFS_RES_DENIED: the file was opened, remove failed
*/
ramfs_res_t ramfs_remove(const char * fn);
/**
* Read data from an opened file
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open )
* @param buf pointer to a memory block where to store the read data
* @param btr number of Bytes To Read
* @param br the real number of read bytes (Byte Read)
* @return RAMFS_RES_OK: no error, the file is read
* any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_read (void * file_p, void * buf, uint32_t btr, uint32_t * br);
/**
* Write data to an opened file
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open)
* @param buf pointer to a memory block which content will be written
* @param btw the number Bytes To Write
* @param bw The real number of written bytes (Byte Written)
* @return RAMFS_RES_OK: no error, the file is read
* any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_write (void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
/**
* Set the read write pointer. Also expand the file size if necessary.
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open )
* @param pos the new position of read write pointer
* @return RAMFS_RES_OK: no error, the file is read
* any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_seek (void * file_p, uint32_t pos);
/**
* Give the position of the read write pointer
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open )
* @param pos_p pointer to to store the result
* @return RAMFS_RES_OK: no error, the file is read
* any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_tell (void * file_p, uint32_t * pos_p);
/**
* Truncate the file size to the current position of the read write pointer
* @param file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open )
* @return RAMFS_RES_OK: no error, the file is read
* any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_trunc (void * file_p);
/**
* Give the size of the file in bytes
* @param file_p file_p pointer to an 'ufs_file_t' variable. (opened with ramfs_open )
* @param size_p pointer to store the size
* @return RAMFS_RES_OK: no error, the file is read
* any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_size (void * file_p, uint32_t * size_p);
/**
* get access info
* @param path uFS doesn't support folders so it has to be ""
* @param mode the info to get
* @return RAMFS_RES_OK or any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_access(const char * path, int mode);
/**
* Create a directory
* @param path uFS doesn't support folders so it has to be ""
* @return RAMFS_RES_OK or any error from lv__fs_res_t enum
*/
ramfs_res_t ramfs_mkdir(const char * path);
/**
* Initialize a ramfs_read_dir_t variable to directory reading
* @param rddir_p pointer to a 'ufs_read_dir_t' variable
* @param path uFS doesn't support folders so it has to be ""
* @return RAMFS_RES_OK or any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_dir_open(void * rddir_p, const char * path);
/**
* Read the next file name
* @param dir_p pointer to an initialized 'ufs_read_dir_t' variable
* @param fn pointer to buffer to sore the file name
* @return RAMFS_RES_OK or any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_dir_read(void * dir_p, char * fn);
/**
* Close the directory reading
* @param rddir_p pointer to an initialized 'ufs_read_dir_t' variable
* @return RAMFS_RES_OK or any error from ramfs_res_t enum
*/
ramfs_res_t ramfs_dir_close(void * rddir_p);
/**
* Give the size of a drive
* @param total_p pointer to store the total size [kB]
* @param free_p pointer to store the free site [kB]
* @return RAMFS_RES_OK or any error from 'fs_res_t'
*/
ramfs_res_t ramfs_free (uint32_t * total_p, uint32_t * free_p);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View file

@ -0,0 +1,15 @@
NAME := ramfs
$(NAME)_TYPE := kernel
$(NAME)_SOURCES += ramfs.c
#default gcc
ifeq ($(COMPILER),)
$(NAME)_CFLAGS += -Wall -Werror
else ifeq ($(COMPILER),gcc)
$(NAME)_CFLAGS += -Wall -Werror
endif
GLOBAL_INCLUDES += .
GLOBAL_INCLUDES += include
GLOBAL_DEFINES += AOS_RAMFS

View file

@ -0,0 +1 @@
This software component is used to help users port third-party programs, but WITHOUT ANY WARRANTY. The entire risk as to the quality and performance of the program is with you. Should the program prove defective, you assume the cost of all necessary servicing, repair or correction. The use of third-party programs must also follow its own permissive license.

View file

@ -0,0 +1,20 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef FS_SPIFFS_H
#define FS_SPIFFS_H
#ifdef __cplusplus
extern "C" {
#endif
int vfs_spiffs_register(void);
int vfs_spiffs_unregister(void);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,408 @@
/*
* spiffs_config.h
*
* Created on: Jul 3, 2013
* Author: petera
*/
#ifndef SPIFFS_CONFIG_H_
#define SPIFFS_CONFIG_H_
// ----------- 8< ------------
// Following includes are for the linux test build of spiffs
// These may/should/must be removed/altered/replaced in your target
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <unistd.h>
#include <aos/aos.h>
// ----------- >8 ------------
/**************************************************************/
/* Customer definations */
// Set SPIFFS partition
#ifdef CONFIG_SPIFFS_PARTITION
#define SPIFFS_CFG_PARTITION CONFIG_SPIFFS_PARTITION
#else
#define SPIFFS_CFG_PARTITION HAL_PARTITION_SPIFFS
#endif
// Set needed types
typedef int32_t s32_t;
typedef uint32_t u32_t;
typedef int16_t s16_t;
typedef uint16_t u16_t;
typedef int8_t s8_t;
typedef uint8_t u8_t;
struct spiffs_t;
extern void _spiffs_lock(struct spiffs_t *fs);
extern void _spiffs_unlock(struct spiffs_t *fs);
// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level
// These should be defined on a multithreaded system
// define this to enter a mutex if you're running on a multithreaded system
#define SPIFFS_LOCK(fs) _spiffs_lock(fs)
// define this to exit a mutex if you're running on a multithreaded system
#define SPIFFS_UNLOCK(fs) _spiffs_unlock(fs)
// Enable if only one spiffs instance with constant configuration will exist
// on the target. This will reduce calculations, flash and memory accesses.
// Parts of configuration must be defined below instead of at time of mount.
#define SPIFFS_SINGLETON 0
// Instead of giving parameters in config struct, singleton build must
// give parameters in defines below.
#ifdef CONFIG_SPIFFS_PHYS_SZ
#define CFG_SPIFFS_PHYS_SZ CONFIG_SPIFFS_PHYS_SZ
#else
#define CFG_SPIFFS_PHYS_SZ (1024 * 1024)
#endif
#ifdef CONFIG_SPIFFS_PHYS_ERASE_SZ
#define CFG_SPIFFS_PHYS_ERASE_SZ CONFIG_SPIFFS_PHYS_ERASE_SZ
#else
#define CFG_SPIFFS_PHYS_ERASE_SZ (64 * 1024)
#endif
#ifdef CONFIG_SPIFFS_PHYS_ADDR
#define CFG_SPIFFS_PHYS_ADDR CONFIG_SPIFFS_PHYS_ADDR
#else
#define CFG_SPIFFS_PHYS_ADDR 0
#endif
#ifdef CONFIG_SPIFFS_LOG_PAGE_SZ
#define CFG_SPIFFS_LOG_PAGE_SZ CONFIG_SPIFFS_LOG_PAGE_SZ
#else
#define CFG_SPIFFS_LOG_PAGE_SZ 256
#endif
#ifdef CONFIG_SPIFFS_LOG_BLOCK_SZ
#define CFG_SPIFFS_LOG_BLOCK_SZ CONFIG_SPIFFS_LOG_BLOCK_SZ
#else
#define CFG_SPIFFS_LOG_BLOCK_SZ (64 * 1024)
#endif
// Set max open file
#ifdef CONFIG_SPIFFS_MAX_FILES
#define CFG_SPIFFS_MAX_FILES CONFIG_SPIFFS_MAX_FILES
#else
#define CFG_SPIFFS_MAX_FILES 4
#endif
/**************************************************************/
// compile time switches
#define SPIFFS_TAG "SPIFFS"
// Set generic spiffs debug output call.
#ifndef SPIFFS_DBG
#define SPIFFS_DBG(...) //LOGD(SPIFFS_TAG, __VA_ARGS__)
#endif
// Set spiffs debug output call for garbage collecting.
#ifndef SPIFFS_GC_DBG
#define SPIFFS_GC_DBG(...) //LOGD(SPIFFS_TAG, __VA_ARGS__)
#endif
// Set spiffs debug output call for caching.
#ifndef SPIFFS_CACHE_DBG
#define SPIFFS_CACHE_DBG(...) //LOGD(SPIFFS_TAG, __VA_ARGS__)
#endif
// Set spiffs debug output call for system consistency checks.
#ifndef SPIFFS_CHECK_DBG
#define SPIFFS_CHECK_DBG(...) //LOGD(SPIFFS_TAG, __VA_ARGS__)
#endif
// Set spiffs debug output call for all api invocations.
#ifndef SPIFFS_API_DBG
#define SPIFFS_API_DBG(...) //LOGD(SPIFFS_TAG, __VA_ARGS__)
#endif
// Defines spiffs debug print formatters
// some general signed number
#ifndef _SPIPRIi
#define _SPIPRIi "%d"
#endif
// address
#ifndef _SPIPRIad
#define _SPIPRIad "%08x"
#endif
// block
#ifndef _SPIPRIbl
#define _SPIPRIbl "%04x"
#endif
// page
#ifndef _SPIPRIpg
#define _SPIPRIpg "%04x"
#endif
// span index
#ifndef _SPIPRIsp
#define _SPIPRIsp "%04x"
#endif
// file descriptor
#ifndef _SPIPRIfd
#define _SPIPRIfd "%d"
#endif
// file object id
#ifndef _SPIPRIid
#define _SPIPRIid "%04x"
#endif
// file flags
#ifndef _SPIPRIfl
#define _SPIPRIfl "%02x"
#endif
// Enable/disable API functions to determine exact number of bytes
// for filedescriptor and cache buffers. Once decided for a configuration,
// this can be disabled to reduce flash.
#ifndef SPIFFS_BUFFER_HELP
#define SPIFFS_BUFFER_HELP 0
#endif
// Enables/disable memory read caching of nucleus file system operations.
// If enabled, memory area must be provided for cache in SPIFFS_mount.
#ifndef SPIFFS_CACHE
#define SPIFFS_CACHE 1
#endif
#if SPIFFS_CACHE
// Enables memory write caching for file descriptors in hydrogen
#ifndef SPIFFS_CACHE_WR
#define SPIFFS_CACHE_WR 1
#endif
// Enable/disable statistics on caching. Debug/test purpose only.
#ifndef SPIFFS_CACHE_STATS
#define SPIFFS_CACHE_STATS 1
#endif
#endif
// Always check header of each accessed page to ensure consistent state.
// If enabled it will increase number of reads, will increase flash.
#ifndef SPIFFS_PAGE_CHECK
#define SPIFFS_PAGE_CHECK 1
#endif
// Define maximum number of gc runs to perform to reach desired free pages.
#ifndef SPIFFS_GC_MAX_RUNS
#define SPIFFS_GC_MAX_RUNS 5
#endif
// Enable/disable statistics on gc. Debug/test purpose only.
#ifndef SPIFFS_GC_STATS
#define SPIFFS_GC_STATS 1
#endif
// Garbage collecting examines all pages in a block which and sums up
// to a block score. Deleted pages normally gives positive score and
// used pages normally gives a negative score (as these must be moved).
// To have a fair wear-leveling, the erase age is also included in score,
// whose factor normally is the most positive.
// The larger the score, the more likely it is that the block will
// picked for garbage collection.
// Garbage collecting heuristics - weight used for deleted pages.
#ifndef SPIFFS_GC_HEUR_W_DELET
#define SPIFFS_GC_HEUR_W_DELET (5)
#endif
// Garbage collecting heuristics - weight used for used pages.
#ifndef SPIFFS_GC_HEUR_W_USED
#define SPIFFS_GC_HEUR_W_USED (-1)
#endif
// Garbage collecting heuristics - weight used for time between
// last erased and erase of this block.
#ifndef SPIFFS_GC_HEUR_W_ERASE_AGE
#define SPIFFS_GC_HEUR_W_ERASE_AGE (50)
#endif
// Object name maximum length. Note that this length include the
// zero-termination character, meaning maximum string of characters
// can at most be SPIFFS_OBJ_NAME_LEN - 1.
#ifndef SPIFFS_OBJ_NAME_LEN
#define SPIFFS_OBJ_NAME_LEN (32)
#endif
// Maximum length of the metadata associated with an object.
// Setting to non-zero value enables metadata-related API but also
// changes the on-disk format, so the change is not backward-compatible.
//
// Do note: the meta length must never exceed
// logical_page_size - (SPIFFS_OBJ_NAME_LEN + 64)
//
// This is derived from following:
// logical_page_size - (SPIFFS_OBJ_NAME_LEN + sizeof(spiffs_page_header) +
// spiffs_object_ix_header fields + at least some LUT entries)
#ifndef SPIFFS_OBJ_META_LEN
#define SPIFFS_OBJ_META_LEN (0)
#endif
// Size of buffer allocated on stack used when copying data.
// Lower value generates more read/writes. No meaning having it bigger
// than logical page size.
#ifndef SPIFFS_COPY_BUFFER_STACK
#define SPIFFS_COPY_BUFFER_STACK (256)
#endif
// Enable this to have an identifiable spiffs filesystem. This will look for
// a magic in all sectors to determine if this is a valid spiffs system or
// not on mount point. If not, SPIFFS_format must be called prior to mounting
// again.
#ifndef SPIFFS_USE_MAGIC
#define SPIFFS_USE_MAGIC (1)
#endif
#if SPIFFS_USE_MAGIC
// Only valid when SPIFFS_USE_MAGIC is enabled. If SPIFFS_USE_MAGIC_LENGTH is
// enabled, the magic will also be dependent on the length of the filesystem.
// For example, a filesystem configured and formatted for 4 megabytes will not
// be accepted for mounting with a configuration defining the filesystem as 2
// megabytes.
#ifndef SPIFFS_USE_MAGIC_LENGTH
#define SPIFFS_USE_MAGIC_LENGTH (1)
#endif
#endif
// Enable this if your target needs aligned data for index tables
#ifndef SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
#define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 0
#endif
// Enable this if you want the HAL callbacks to be called with the spiffs struct
#ifndef SPIFFS_HAL_CALLBACK_EXTRA
#define SPIFFS_HAL_CALLBACK_EXTRA 0
#endif
// Enable this if you want to add an integer offset to all file handles
// (spiffs_file). This is useful if running multiple instances of spiffs on
// same target, in order to recognise to what spiffs instance a file handle
// belongs.
// NB: This adds config field fh_ix_offset in the configuration struct when
// mounting, which must be defined.
#ifndef SPIFFS_FILEHDL_OFFSET
#define SPIFFS_FILEHDL_OFFSET 0
#endif
// Enable this to compile a read only version of spiffs.
// This will reduce binary size of spiffs. All code comprising modification
// of the file system will not be compiled. Some config will be ignored.
// HAL functions for erasing and writing to spi-flash may be null. Cache
// can be disabled for even further binary size reduction (and ram savings).
// Functions modifying the fs will return SPIFFS_ERR_RO_NOT_IMPL.
// If the file system cannot be mounted due to aborted erase operation and
// SPIFFS_USE_MAGIC is enabled, SPIFFS_ERR_RO_ABORTED_OPERATION will be
// returned.
// Might be useful for e.g. bootloaders and such.
#ifndef SPIFFS_READ_ONLY
#define SPIFFS_READ_ONLY 0
#endif
// Enable this to add a temporal file cache using the fd buffer.
// The effects of the cache is that SPIFFS_open will find the file faster in
// certain cases. It will make it a lot easier for spiffs to find files
// opened frequently, reducing number of readings from the spi flash for
// finding those files.
// This will grow each fd by 6 bytes. If your files are opened in patterns
// with a degree of temporal locality, the system is optimized.
// Examples can be letting spiffs serve web content, where one file is the css.
// The css is accessed for each html file that is opened, meaning it is
// accessed almost every second time a file is opened. Another example could be
// a log file that is often opened, written, and closed.
// The size of the cache is number of given file descriptors, as it piggybacks
// on the fd update mechanism. The cache lives in the closed file descriptors.
// When closed, the fd know the whereabouts of the file. Instead of forgetting
// this, the temporal cache will keep handling updates to that file even if the
// fd is closed. If the file is opened again, the location of the file is found
// directly. If all available descriptors become opened, all cache memory is
// lost.
#ifndef SPIFFS_TEMPORAL_FD_CACHE
#define SPIFFS_TEMPORAL_FD_CACHE 1
#endif
// Temporal file cache hit score. Each time a file is opened, all cached files
// will lose one point. If the opened file is found in cache, that entry will
// gain SPIFFS_TEMPORAL_CACHE_HIT_SCORE points. One can experiment with this
// value for the specific access patterns of the application. However, it must
// be between 1 (no gain for hitting a cached entry often) and 255.
#ifndef SPIFFS_TEMPORAL_CACHE_HIT_SCORE
#define SPIFFS_TEMPORAL_CACHE_HIT_SCORE 4
#endif
// Enable to be able to map object indices to memory.
// This allows for faster and more deterministic reading if cases of reading
// large files and when changing file offset by seeking around a lot.
// When mapping a file's index, the file system will be scanned for index pages
// and the info will be put in memory provided by user. When reading, the
// memory map can be looked up instead of searching for index pages on the
// medium. This way, user can trade memory against performance.
// Whole, parts of, or future parts not being written yet can be mapped. The
// memory array will be owned by spiffs and updated accordingly during garbage
// collecting or when modifying the indices. The latter is invoked by when the
// file is modified in some way. The index buffer is tied to the file
// descriptor.
#ifndef SPIFFS_IX_MAP
#define SPIFFS_IX_MAP 1
#endif
// By default SPIFFS in some cases relies on the property of NOR flash that bits
// cannot be set from 0 to 1 by writing and that controllers will ignore such
// bit changes. This results in fewer reads as SPIFFS can in some cases perform
// blind writes, with all bits set to 1 and only those it needs reset set to 0.
// Most of the chips and controllers allow this behavior, so the default is to
// use this technique. If your controller is one of the rare ones that don't,
// turn this option on and SPIFFS will perform a read-modify-write instead.
#ifndef SPIFFS_NO_BLIND_WRITES
#define SPIFFS_NO_BLIND_WRITES 0
#endif
// Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function
// in the api. This function will visualize all filesystem using given printf
// function.
#ifndef SPIFFS_TEST_VISUALISATION
#define SPIFFS_TEST_VISUALISATION 0
#endif
#if SPIFFS_TEST_VISUALISATION
#ifndef spiffs_printf
#define spiffs_printf(...) LOGD(SPIFFS_TAG, __VA_ARGS__)
#endif
// spiffs_printf argument for a free page
#ifndef SPIFFS_TEST_VIS_FREE_STR
#define SPIFFS_TEST_VIS_FREE_STR "_"
#endif
// spiffs_printf argument for a deleted page
#ifndef SPIFFS_TEST_VIS_DELE_STR
#define SPIFFS_TEST_VIS_DELE_STR "/"
#endif
// spiffs_printf argument for an index page for given object id
#ifndef SPIFFS_TEST_VIS_INDX_STR
#define SPIFFS_TEST_VIS_INDX_STR(id) "i"
#endif
// spiffs_printf argument for a data page for given object id
#ifndef SPIFFS_TEST_VIS_DATA_STR
#define SPIFFS_TEST_VIS_DATA_STR(id) "d"
#endif
#endif
// Types depending on configuration such as the amount of flash bytes
// given to spiffs file system in total (spiffs_file_system_size),
// the logical block size (log_block_size), and the logical page size
// (log_page_size)
// Block index type. Make sure the size of this type can hold
// the highest number of all blocks - i.e. spiffs_file_system_size / log_block_size
typedef u16_t spiffs_block_ix;
// Page index type. Make sure the size of this type can hold
// the highest page number of all pages - i.e. spiffs_file_system_size / log_page_size
typedef u16_t spiffs_page_ix;
// Object id type - most significant bit is reserved for index flag. Make sure the
// size of this type can hold the highest object id on a full system,
// i.e. 2 + (spiffs_file_system_size / (2*log_page_size))*2
typedef u16_t spiffs_obj_id;
// Object span index type. Make sure the size of this type can
// hold the largest possible span index on the system -
// i.e. (spiffs_file_system_size / log_page_size) - 1
typedef u16_t spiffs_span_ix;
#endif /* SPIFFS_CONFIG_H_ */

View file

@ -0,0 +1,20 @@
NAME := spiffs
$(NAME)_TYPE := kernel
$(NAME)_SOURCES += spiffs_port.c \
spiffs/spiffs_cache.c \
spiffs/spiffs_check.c \
spiffs/spiffs_gc.c \
spiffs/spiffs_hydrogen.c \
spiffs/spiffs_nucleus.c
#default gcc
ifeq ($(COMPILER),)
$(NAME)_CFLAGS += -Wall -Werror
else ifeq ($(COMPILER),gcc)
$(NAME)_CFLAGS += -Wall -Werror
endif
GLOBAL_INCLUDES += include spiffs/include
GLOBAL_DEFINES += AOS_SPIFFS

View file

@ -0,0 +1,373 @@
/*
* spiffs_config.h
*
* Created on: Jul 3, 2013
* Author: petera
*/
#ifndef SPIFFS_CONFIG_H_
#define SPIFFS_CONFIG_H_
// ----------- 8< ------------
// Following includes are for the linux test build of spiffs
// These may/should/must be removed/altered/replaced in your target
#include "params_test.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <unistd.h>
#ifdef _SPIFFS_TEST
#include "testrunner.h"
#endif
// ----------- >8 ------------
// compile time switches
// Set generic spiffs debug output call.
#ifndef SPIFFS_DBG
#define SPIFFS_DBG(_f, ...) //printf(_f, ## __VA_ARGS__)
#endif
// Set spiffs debug output call for garbage collecting.
#ifndef SPIFFS_GC_DBG
#define SPIFFS_GC_DBG(_f, ...) //printf(_f, ## __VA_ARGS__)
#endif
// Set spiffs debug output call for caching.
#ifndef SPIFFS_CACHE_DBG
#define SPIFFS_CACHE_DBG(_f, ...) //printf(_f, ## __VA_ARGS__)
#endif
// Set spiffs debug output call for system consistency checks.
#ifndef SPIFFS_CHECK_DBG
#define SPIFFS_CHECK_DBG(_f, ...) //printf(_f, ## __VA_ARGS__)
#endif
// Set spiffs debug output call for all api invocations.
#ifndef SPIFFS_API_DBG
#define SPIFFS_API_DBG(_f, ...) //printf(_f, ## __VA_ARGS__)
#endif
// Defines spiffs debug print formatters
// some general signed number
#ifndef _SPIPRIi
#define _SPIPRIi "%d"
#endif
// address
#ifndef _SPIPRIad
#define _SPIPRIad "%08x"
#endif
// block
#ifndef _SPIPRIbl
#define _SPIPRIbl "%04x"
#endif
// page
#ifndef _SPIPRIpg
#define _SPIPRIpg "%04x"
#endif
// span index
#ifndef _SPIPRIsp
#define _SPIPRIsp "%04x"
#endif
// file descriptor
#ifndef _SPIPRIfd
#define _SPIPRIfd "%d"
#endif
// file object id
#ifndef _SPIPRIid
#define _SPIPRIid "%04x"
#endif
// file flags
#ifndef _SPIPRIfl
#define _SPIPRIfl "%02x"
#endif
// Enable/disable API functions to determine exact number of bytes
// for filedescriptor and cache buffers. Once decided for a configuration,
// this can be disabled to reduce flash.
#ifndef SPIFFS_BUFFER_HELP
#define SPIFFS_BUFFER_HELP 0
#endif
// Enables/disable memory read caching of nucleus file system operations.
// If enabled, memory area must be provided for cache in SPIFFS_mount.
#ifndef SPIFFS_CACHE
#define SPIFFS_CACHE 1
#endif
#if SPIFFS_CACHE
// Enables memory write caching for file descriptors in hydrogen
#ifndef SPIFFS_CACHE_WR
#define SPIFFS_CACHE_WR 1
#endif
// Enable/disable statistics on caching. Debug/test purpose only.
#ifndef SPIFFS_CACHE_STATS
#define SPIFFS_CACHE_STATS 1
#endif
#endif
// Always check header of each accessed page to ensure consistent state.
// If enabled it will increase number of reads, will increase flash.
#ifndef SPIFFS_PAGE_CHECK
#define SPIFFS_PAGE_CHECK 1
#endif
// Define maximum number of gc runs to perform to reach desired free pages.
#ifndef SPIFFS_GC_MAX_RUNS
#define SPIFFS_GC_MAX_RUNS 5
#endif
// Enable/disable statistics on gc. Debug/test purpose only.
#ifndef SPIFFS_GC_STATS
#define SPIFFS_GC_STATS 1
#endif
// Garbage collecting examines all pages in a block which and sums up
// to a block score. Deleted pages normally gives positive score and
// used pages normally gives a negative score (as these must be moved).
// To have a fair wear-leveling, the erase age is also included in score,
// whose factor normally is the most positive.
// The larger the score, the more likely it is that the block will
// picked for garbage collection.
// Garbage collecting heuristics - weight used for deleted pages.
#ifndef SPIFFS_GC_HEUR_W_DELET
#define SPIFFS_GC_HEUR_W_DELET (5)
#endif
// Garbage collecting heuristics - weight used for used pages.
#ifndef SPIFFS_GC_HEUR_W_USED
#define SPIFFS_GC_HEUR_W_USED (-1)
#endif
// Garbage collecting heuristics - weight used for time between
// last erased and erase of this block.
#ifndef SPIFFS_GC_HEUR_W_ERASE_AGE
#define SPIFFS_GC_HEUR_W_ERASE_AGE (50)
#endif
// Object name maximum length. Note that this length include the
// zero-termination character, meaning maximum string of characters
// can at most be SPIFFS_OBJ_NAME_LEN - 1.
#ifndef SPIFFS_OBJ_NAME_LEN
#define SPIFFS_OBJ_NAME_LEN (32)
#endif
// Maximum length of the metadata associated with an object.
// Setting to non-zero value enables metadata-related API but also
// changes the on-disk format, so the change is not backward-compatible.
//
// Do note: the meta length must never exceed
// logical_page_size - (SPIFFS_OBJ_NAME_LEN + 64)
//
// This is derived from following:
// logical_page_size - (SPIFFS_OBJ_NAME_LEN + sizeof(spiffs_page_header) +
// spiffs_object_ix_header fields + at least some LUT entries)
#ifndef SPIFFS_OBJ_META_LEN
#define SPIFFS_OBJ_META_LEN (0)
#endif
// Size of buffer allocated on stack used when copying data.
// Lower value generates more read/writes. No meaning having it bigger
// than logical page size.
#ifndef SPIFFS_COPY_BUFFER_STACK
#define SPIFFS_COPY_BUFFER_STACK (64)
#endif
// Enable this to have an identifiable spiffs filesystem. This will look for
// a magic in all sectors to determine if this is a valid spiffs system or
// not on mount point. If not, SPIFFS_format must be called prior to mounting
// again.
#ifndef SPIFFS_USE_MAGIC
#define SPIFFS_USE_MAGIC (0)
#endif
#if SPIFFS_USE_MAGIC
// Only valid when SPIFFS_USE_MAGIC is enabled. If SPIFFS_USE_MAGIC_LENGTH is
// enabled, the magic will also be dependent on the length of the filesystem.
// For example, a filesystem configured and formatted for 4 megabytes will not
// be accepted for mounting with a configuration defining the filesystem as 2
// megabytes.
#ifndef SPIFFS_USE_MAGIC_LENGTH
#define SPIFFS_USE_MAGIC_LENGTH (0)
#endif
#endif
// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level
// These should be defined on a multithreaded system
// define this to enter a mutex if you're running on a multithreaded system
#ifndef SPIFFS_LOCK
#define SPIFFS_LOCK(fs)
#endif
// define this to exit a mutex if you're running on a multithreaded system
#ifndef SPIFFS_UNLOCK
#define SPIFFS_UNLOCK(fs)
#endif
// Enable if only one spiffs instance with constant configuration will exist
// on the target. This will reduce calculations, flash and memory accesses.
// Parts of configuration must be defined below instead of at time of mount.
#ifndef SPIFFS_SINGLETON
#define SPIFFS_SINGLETON 0
#endif
#if SPIFFS_SINGLETON
// Instead of giving parameters in config struct, singleton build must
// give parameters in defines below.
#ifndef SPIFFS_CFG_PHYS_SZ
#define SPIFFS_CFG_PHYS_SZ(ignore) (1024*1024*2)
#endif
#ifndef SPIFFS_CFG_PHYS_ERASE_SZ
#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (65536)
#endif
#ifndef SPIFFS_CFG_PHYS_ADDR
#define SPIFFS_CFG_PHYS_ADDR(ignore) (0)
#endif
#ifndef SPIFFS_CFG_LOG_PAGE_SZ
#define SPIFFS_CFG_LOG_PAGE_SZ(ignore) (256)
#endif
#ifndef SPIFFS_CFG_LOG_BLOCK_SZ
#define SPIFFS_CFG_LOG_BLOCK_SZ(ignore) (65536)
#endif
#endif
// Enable this if your target needs aligned data for index tables
#ifndef SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
#define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 0
#endif
// Enable this if you want the HAL callbacks to be called with the spiffs struct
#ifndef SPIFFS_HAL_CALLBACK_EXTRA
#define SPIFFS_HAL_CALLBACK_EXTRA 0
#endif
// Enable this if you want to add an integer offset to all file handles
// (spiffs_file). This is useful if running multiple instances of spiffs on
// same target, in order to recognise to what spiffs instance a file handle
// belongs.
// NB: This adds config field fh_ix_offset in the configuration struct when
// mounting, which must be defined.
#ifndef SPIFFS_FILEHDL_OFFSET
#define SPIFFS_FILEHDL_OFFSET 0
#endif
// Enable this to compile a read only version of spiffs.
// This will reduce binary size of spiffs. All code comprising modification
// of the file system will not be compiled. Some config will be ignored.
// HAL functions for erasing and writing to spi-flash may be null. Cache
// can be disabled for even further binary size reduction (and ram savings).
// Functions modifying the fs will return SPIFFS_ERR_RO_NOT_IMPL.
// If the file system cannot be mounted due to aborted erase operation and
// SPIFFS_USE_MAGIC is enabled, SPIFFS_ERR_RO_ABORTED_OPERATION will be
// returned.
// Might be useful for e.g. bootloaders and such.
#ifndef SPIFFS_READ_ONLY
#define SPIFFS_READ_ONLY 0
#endif
// Enable this to add a temporal file cache using the fd buffer.
// The effects of the cache is that SPIFFS_open will find the file faster in
// certain cases. It will make it a lot easier for spiffs to find files
// opened frequently, reducing number of readings from the spi flash for
// finding those files.
// This will grow each fd by 6 bytes. If your files are opened in patterns
// with a degree of temporal locality, the system is optimized.
// Examples can be letting spiffs serve web content, where one file is the css.
// The css is accessed for each html file that is opened, meaning it is
// accessed almost every second time a file is opened. Another example could be
// a log file that is often opened, written, and closed.
// The size of the cache is number of given file descriptors, as it piggybacks
// on the fd update mechanism. The cache lives in the closed file descriptors.
// When closed, the fd know the whereabouts of the file. Instead of forgetting
// this, the temporal cache will keep handling updates to that file even if the
// fd is closed. If the file is opened again, the location of the file is found
// directly. If all available descriptors become opened, all cache memory is
// lost.
#ifndef SPIFFS_TEMPORAL_FD_CACHE
#define SPIFFS_TEMPORAL_FD_CACHE 1
#endif
// Temporal file cache hit score. Each time a file is opened, all cached files
// will lose one point. If the opened file is found in cache, that entry will
// gain SPIFFS_TEMPORAL_CACHE_HIT_SCORE points. One can experiment with this
// value for the specific access patterns of the application. However, it must
// be between 1 (no gain for hitting a cached entry often) and 255.
#ifndef SPIFFS_TEMPORAL_CACHE_HIT_SCORE
#define SPIFFS_TEMPORAL_CACHE_HIT_SCORE 4
#endif
// Enable to be able to map object indices to memory.
// This allows for faster and more deterministic reading if cases of reading
// large files and when changing file offset by seeking around a lot.
// When mapping a file's index, the file system will be scanned for index pages
// and the info will be put in memory provided by user. When reading, the
// memory map can be looked up instead of searching for index pages on the
// medium. This way, user can trade memory against performance.
// Whole, parts of, or future parts not being written yet can be mapped. The
// memory array will be owned by spiffs and updated accordingly during garbage
// collecting or when modifying the indices. The latter is invoked by when the
// file is modified in some way. The index buffer is tied to the file
// descriptor.
#ifndef SPIFFS_IX_MAP
#define SPIFFS_IX_MAP 1
#endif
// By default SPIFFS in some cases relies on the property of NOR flash that bits
// cannot be set from 0 to 1 by writing and that controllers will ignore such
// bit changes. This results in fewer reads as SPIFFS can in some cases perform
// blind writes, with all bits set to 1 and only those it needs reset set to 0.
// Most of the chips and controllers allow this behavior, so the default is to
// use this technique. If your controller is one of the rare ones that don't,
// turn this option on and SPIFFS will perform a read-modify-write instead.
#ifndef SPIFFS_NO_BLIND_WRITES
#define SPIFFS_NO_BLIND_WRITES 0
#endif
// Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function
// in the api. This function will visualize all filesystem using given printf
// function.
#ifndef SPIFFS_TEST_VISUALISATION
#define SPIFFS_TEST_VISUALISATION 1
#endif
#if SPIFFS_TEST_VISUALISATION
#ifndef spiffs_printf
#define spiffs_printf(...) printf(__VA_ARGS__)
#endif
// spiffs_printf argument for a free page
#ifndef SPIFFS_TEST_VIS_FREE_STR
#define SPIFFS_TEST_VIS_FREE_STR "_"
#endif
// spiffs_printf argument for a deleted page
#ifndef SPIFFS_TEST_VIS_DELE_STR
#define SPIFFS_TEST_VIS_DELE_STR "/"
#endif
// spiffs_printf argument for an index page for given object id
#ifndef SPIFFS_TEST_VIS_INDX_STR
#define SPIFFS_TEST_VIS_INDX_STR(id) "i"
#endif
// spiffs_printf argument for a data page for given object id
#ifndef SPIFFS_TEST_VIS_DATA_STR
#define SPIFFS_TEST_VIS_DATA_STR(id) "d"
#endif
#endif
// Types depending on configuration such as the amount of flash bytes
// given to spiffs file system in total (spiffs_file_system_size),
// the logical block size (log_block_size), and the logical page size
// (log_page_size)
// Block index type. Make sure the size of this type can hold
// the highest number of all blocks - i.e. spiffs_file_system_size / log_block_size
typedef u16_t spiffs_block_ix;
// Page index type. Make sure the size of this type can hold
// the highest page number of all pages - i.e. spiffs_file_system_size / log_page_size
typedef u16_t spiffs_page_ix;
// Object id type - most significant bit is reserved for index flag. Make sure the
// size of this type can hold the highest object id on a full system,
// i.e. 2 + (spiffs_file_system_size / (2*log_page_size))*2
typedef u16_t spiffs_obj_id;
// Object span index type. Make sure the size of this type can
// hold the largest possible span index on the system -
// i.e. (spiffs_file_system_size / log_page_size) - 1
typedef u16_t spiffs_span_ix;
#endif /* SPIFFS_CONFIG_H_ */

View file

@ -0,0 +1,816 @@
/*
* spiffs.h
*
* Created on: May 26, 2013
* Author: petera
*/
#ifndef SPIFFS_H_
#define SPIFFS_H_
#if defined(__cplusplus)
extern "C" {
#endif
#include "spiffs_config.h"
#define SPIFFS_OK 0
#define SPIFFS_ERR_NOT_MOUNTED -10000
#define SPIFFS_ERR_FULL -10001
#define SPIFFS_ERR_NOT_FOUND -10002
#define SPIFFS_ERR_END_OF_OBJECT -10003
#define SPIFFS_ERR_DELETED -10004
#define SPIFFS_ERR_NOT_FINALIZED -10005
#define SPIFFS_ERR_NOT_INDEX -10006
#define SPIFFS_ERR_OUT_OF_FILE_DESCS -10007
#define SPIFFS_ERR_FILE_CLOSED -10008
#define SPIFFS_ERR_FILE_DELETED -10009
#define SPIFFS_ERR_BAD_DESCRIPTOR -10010
#define SPIFFS_ERR_IS_INDEX -10011
#define SPIFFS_ERR_IS_FREE -10012
#define SPIFFS_ERR_INDEX_SPAN_MISMATCH -10013
#define SPIFFS_ERR_DATA_SPAN_MISMATCH -10014
#define SPIFFS_ERR_INDEX_REF_FREE -10015
#define SPIFFS_ERR_INDEX_REF_LU -10016
#define SPIFFS_ERR_INDEX_REF_INVALID -10017
#define SPIFFS_ERR_INDEX_FREE -10018
#define SPIFFS_ERR_INDEX_LU -10019
#define SPIFFS_ERR_INDEX_INVALID -10020
#define SPIFFS_ERR_NOT_WRITABLE -10021
#define SPIFFS_ERR_NOT_READABLE -10022
#define SPIFFS_ERR_CONFLICTING_NAME -10023
#define SPIFFS_ERR_NOT_CONFIGURED -10024
#define SPIFFS_ERR_NOT_A_FS -10025
#define SPIFFS_ERR_MOUNTED -10026
#define SPIFFS_ERR_ERASE_FAIL -10027
#define SPIFFS_ERR_MAGIC_NOT_POSSIBLE -10028
#define SPIFFS_ERR_NO_DELETED_BLOCKS -10029
#define SPIFFS_ERR_FILE_EXISTS -10030
#define SPIFFS_ERR_NOT_A_FILE -10031
#define SPIFFS_ERR_RO_NOT_IMPL -10032
#define SPIFFS_ERR_RO_ABORTED_OPERATION -10033
#define SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS -10034
#define SPIFFS_ERR_PROBE_NOT_A_FS -10035
#define SPIFFS_ERR_NAME_TOO_LONG -10036
#define SPIFFS_ERR_IX_MAP_UNMAPPED -10037
#define SPIFFS_ERR_IX_MAP_MAPPED -10038
#define SPIFFS_ERR_IX_MAP_BAD_RANGE -10039
#define SPIFFS_ERR_SEEK_BOUNDS -10040
#define SPIFFS_ERR_INTERNAL -10050
#define SPIFFS_ERR_TEST -10100
// spiffs file descriptor index type. must be signed
typedef s16_t spiffs_file;
// spiffs file descriptor flags
typedef u16_t spiffs_flags;
// spiffs file mode
typedef u16_t spiffs_mode;
// object type
typedef u8_t spiffs_obj_type;
struct spiffs_t;
#if SPIFFS_HAL_CALLBACK_EXTRA
/* spi read call function type */
typedef s32_t (*spiffs_read)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *dst);
/* spi write call function type */
typedef s32_t (*spiffs_write)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *src);
/* spi erase call function type */
typedef s32_t (*spiffs_erase)(struct spiffs_t *fs, u32_t addr, u32_t size);
#else // SPIFFS_HAL_CALLBACK_EXTRA
/* spi read call function type */
typedef s32_t (*spiffs_read)(u32_t addr, u32_t size, u8_t *dst);
/* spi write call function type */
typedef s32_t (*spiffs_write)(u32_t addr, u32_t size, u8_t *src);
/* spi erase call function type */
typedef s32_t (*spiffs_erase)(u32_t addr, u32_t size);
#endif // SPIFFS_HAL_CALLBACK_EXTRA
/* file system check callback report operation */
typedef enum {
SPIFFS_CHECK_LOOKUP = 0,
SPIFFS_CHECK_INDEX,
SPIFFS_CHECK_PAGE
} spiffs_check_type;
/* file system check callback report type */
typedef enum {
SPIFFS_CHECK_PROGRESS = 0,
SPIFFS_CHECK_ERROR,
SPIFFS_CHECK_FIX_INDEX,
SPIFFS_CHECK_FIX_LOOKUP,
SPIFFS_CHECK_DELETE_ORPHANED_INDEX,
SPIFFS_CHECK_DELETE_PAGE,
SPIFFS_CHECK_DELETE_BAD_FILE
} spiffs_check_report;
/* file system check callback function */
#if SPIFFS_HAL_CALLBACK_EXTRA
typedef void (*spiffs_check_callback)(struct spiffs_t *fs, spiffs_check_type type, spiffs_check_report report,
u32_t arg1, u32_t arg2);
#else // SPIFFS_HAL_CALLBACK_EXTRA
typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report,
u32_t arg1, u32_t arg2);
#endif // SPIFFS_HAL_CALLBACK_EXTRA
/* file system listener callback operation */
typedef enum {
/* the file has been created */
SPIFFS_CB_CREATED = 0,
/* the file has been updated or moved to another page */
SPIFFS_CB_UPDATED,
/* the file has been deleted */
SPIFFS_CB_DELETED
} spiffs_fileop_type;
/* file system listener callback function */
typedef void (*spiffs_file_callback)(struct spiffs_t *fs, spiffs_fileop_type op, spiffs_obj_id obj_id, spiffs_page_ix pix);
#ifndef SPIFFS_DBG
#define SPIFFS_DBG(...) \
printf(__VA_ARGS__)
#endif
#ifndef SPIFFS_GC_DBG
#define SPIFFS_GC_DBG(...) printf(__VA_ARGS__)
#endif
#ifndef SPIFFS_CACHE_DBG
#define SPIFFS_CACHE_DBG(...) printf(__VA_ARGS__)
#endif
#ifndef SPIFFS_CHECK_DBG
#define SPIFFS_CHECK_DBG(...) printf(__VA_ARGS__)
#endif
/* Any write to the filehandle is appended to end of the file */
#define SPIFFS_APPEND (1<<0)
#define SPIFFS_O_APPEND SPIFFS_APPEND
/* If the opened file exists, it will be truncated to zero length before opened */
#define SPIFFS_TRUNC (1<<1)
#define SPIFFS_O_TRUNC SPIFFS_TRUNC
/* If the opened file does not exist, it will be created before opened */
#define SPIFFS_CREAT (1<<2)
#define SPIFFS_O_CREAT SPIFFS_CREAT
/* The opened file may only be read */
#define SPIFFS_RDONLY (1<<3)
#define SPIFFS_O_RDONLY SPIFFS_RDONLY
/* The opened file may only be written */
#define SPIFFS_WRONLY (1<<4)
#define SPIFFS_O_WRONLY SPIFFS_WRONLY
/* The opened file may be both read and written */
#define SPIFFS_RDWR (SPIFFS_RDONLY | SPIFFS_WRONLY)
#define SPIFFS_O_RDWR SPIFFS_RDWR
/* Any writes to the filehandle will never be cached but flushed directly */
#define SPIFFS_DIRECT (1<<5)
#define SPIFFS_O_DIRECT SPIFFS_DIRECT
/* If SPIFFS_O_CREAT and SPIFFS_O_EXCL are set, SPIFFS_open() shall fail if the file exists */
#define SPIFFS_EXCL (1<<6)
#define SPIFFS_O_EXCL SPIFFS_EXCL
#define SPIFFS_SEEK_SET (0)
#define SPIFFS_SEEK_CUR (1)
#define SPIFFS_SEEK_END (2)
#define SPIFFS_TYPE_FILE (1)
#define SPIFFS_TYPE_DIR (2)
#define SPIFFS_TYPE_HARD_LINK (3)
#define SPIFFS_TYPE_SOFT_LINK (4)
#ifndef SPIFFS_LOCK
#define SPIFFS_LOCK(fs)
#endif
#ifndef SPIFFS_UNLOCK
#define SPIFFS_UNLOCK(fs)
#endif
// phys structs
// spiffs spi configuration struct
typedef struct {
// physical read function
spiffs_read hal_read_f;
// physical write function
spiffs_write hal_write_f;
// physical erase function
spiffs_erase hal_erase_f;
#if SPIFFS_SINGLETON == 0
// physical size of the spi flash
u32_t phys_size;
// physical offset in spi flash used for spiffs,
// must be on block boundary
u32_t phys_addr;
// physical size when erasing a block
u32_t phys_erase_block;
// logical size of a block, must be on physical
// block size boundary and must never be less than
// a physical block
u32_t log_block_size;
// logical size of a page, must be at least
// log_block_size / 8
u32_t log_page_size;
#endif
#if SPIFFS_FILEHDL_OFFSET
// an integer offset added to each file handle
u16_t fh_ix_offset;
#endif
} spiffs_config;
typedef struct spiffs_t {
// file system configuration
spiffs_config cfg;
// number of logical blocks
u32_t block_count;
// cursor for free blocks, block index
spiffs_block_ix free_cursor_block_ix;
// cursor for free blocks, entry index
int free_cursor_obj_lu_entry;
// cursor when searching, block index
spiffs_block_ix cursor_block_ix;
// cursor when searching, entry index
int cursor_obj_lu_entry;
// primary work buffer, size of a logical page
u8_t *lu_work;
// secondary work buffer, size of a logical page
u8_t *work;
// file descriptor memory area
u8_t *fd_space;
// available file descriptors
u32_t fd_count;
// last error
s32_t err_code;
// current number of free blocks
u32_t free_blocks;
// current number of busy pages
u32_t stats_p_allocated;
// current number of deleted pages
u32_t stats_p_deleted;
// flag indicating that garbage collector is cleaning
u8_t cleaning;
// max erase count amongst all blocks
spiffs_obj_id max_erase_count;
#if SPIFFS_GC_STATS
u32_t stats_gc_runs;
#endif
#if SPIFFS_CACHE
// cache memory
void *cache;
// cache size
u32_t cache_size;
#if SPIFFS_CACHE_STATS
u32_t cache_hits;
u32_t cache_misses;
#endif
#endif
// check callback function
spiffs_check_callback check_cb_f;
// file callback function
spiffs_file_callback file_cb_f;
// mounted flag
u8_t mounted;
// user data
void *user_data;
// config magic
u32_t config_magic;
} spiffs;
/* spiffs file status struct */
typedef struct {
spiffs_obj_id obj_id;
u32_t size;
spiffs_obj_type type;
spiffs_page_ix pix;
u8_t name[SPIFFS_OBJ_NAME_LEN];
#if SPIFFS_OBJ_META_LEN
u8_t meta[SPIFFS_OBJ_META_LEN];
#endif
} spiffs_stat;
struct spiffs_dirent {
spiffs_obj_id obj_id;
u8_t name[SPIFFS_OBJ_NAME_LEN];
spiffs_obj_type type;
u32_t size;
spiffs_page_ix pix;
#if SPIFFS_OBJ_META_LEN
u8_t meta[SPIFFS_OBJ_META_LEN];
#endif
};
typedef struct {
spiffs *fs;
spiffs_block_ix block;
int entry;
} spiffs_DIR;
#if SPIFFS_IX_MAP
typedef struct {
// buffer with looked up data pixes
spiffs_page_ix *map_buf;
// precise file byte offset
u32_t offset;
// start data span index of lookup buffer
spiffs_span_ix start_spix;
// end data span index of lookup buffer
spiffs_span_ix end_spix;
} spiffs_ix_map;
#endif
// functions
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0
/**
* Special function. This takes a spiffs config struct and returns the number
* of blocks this file system was formatted with. This function relies on
* that following info is set correctly in given config struct:
*
* phys_addr, log_page_size, and log_block_size.
*
* Also, hal_read_f must be set in the config struct.
*
* One must be sure of the correct page size and that the physical address is
* correct in the probed file system when calling this function. It is not
* checked if the phys_addr actually points to the start of the file system,
* so one might get a false positive if entering a phys_addr somewhere in the
* middle of the file system at block boundary. In addition, it is not checked
* if the page size is actually correct. If it is not, weird file system sizes
* will be returned.
*
* If this function detects a file system it returns the assumed file system
* size, which can be used to set the phys_size.
*
* Otherwise, it returns an error indicating why it is not regarded as a file
* system.
*
* Note: this function is not protected with SPIFFS_LOCK and SPIFFS_UNLOCK
* macros. It returns the error code directly, instead of as read by
* SPIFFS_errno.
*
* @param config essential parts of the physical and logical
* configuration of the file system.
*/
s32_t SPIFFS_probe_fs(spiffs_config *config);
#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0
/**
* Initializes the file system dynamic parameters and mounts the filesystem.
* If SPIFFS_USE_MAGIC is enabled the mounting may fail with SPIFFS_ERR_NOT_A_FS
* if the flash does not contain a recognizable file system.
* In this case, SPIFFS_format must be called prior to remounting.
* @param fs the file system struct
* @param config the physical and logical configuration of the file system
* @param work a memory work buffer comprising 2*config->log_page_size
* bytes used throughout all file system operations
* @param fd_space memory for file descriptors
* @param fd_space_size memory size of file descriptors
* @param cache memory for cache, may be null
* @param cache_size memory size of cache
* @param check_cb_f callback function for reporting during consistency checks
*/
s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
u8_t *fd_space, u32_t fd_space_size,
void *cache, u32_t cache_size,
spiffs_check_callback check_cb_f);
/**
* Unmounts the file system. All file handles will be flushed of any
* cached writes and closed.
* @param fs the file system struct
*/
void SPIFFS_unmount(spiffs *fs);
/**
* Creates a new file.
* @param fs the file system struct
* @param path the path of the new file
* @param mode ignored, for posix compliance
*/
s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode);
/**
* Opens/creates a file.
* @param fs the file system struct
* @param path the path of the new file
* @param flags the flags for the open command, can be combinations of
* SPIFFS_O_APPEND, SPIFFS_O_TRUNC, SPIFFS_O_CREAT, SPIFFS_O_RDONLY,
* SPIFFS_O_WRONLY, SPIFFS_O_RDWR, SPIFFS_O_DIRECT, SPIFFS_O_EXCL
* @param mode ignored, for posix compliance
*/
spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode);
/**
* Opens a file by given dir entry.
* Optimization purposes, when traversing a file system with SPIFFS_readdir
* a normal SPIFFS_open would need to traverse the filesystem again to find
* the file, whilst SPIFFS_open_by_dirent already knows where the file resides.
* @param fs the file system struct
* @param e the dir entry to the file
* @param flags the flags for the open command, can be combinations of
* SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY,
* SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT.
* SPIFFS_CREAT will have no effect in this case.
* @param mode ignored, for posix compliance
*/
spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode);
/**
* Opens a file by given page index.
* Optimization purposes, opens a file by directly pointing to the page
* index in the spi flash.
* If the page index does not point to a file header SPIFFS_ERR_NOT_A_FILE
* is returned.
* @param fs the file system struct
* @param page_ix the page index
* @param flags the flags for the open command, can be combinations of
* SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY,
* SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT.
* SPIFFS_CREAT will have no effect in this case.
* @param mode ignored, for posix compliance
*/
spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode);
/**
* Reads from given filehandle.
* @param fs the file system struct
* @param fh the filehandle
* @param buf where to put read data
* @param len how much to read
* @returns number of bytes read, or -1 if error
*/
s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len);
/**
* Writes to given filehandle.
* @param fs the file system struct
* @param fh the filehandle
* @param buf the data to write
* @param len how much to write
* @returns number of bytes written, or -1 if error
*/
s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len);
/**
* Moves the read/write file offset. Resulting offset is returned or negative if error.
* lseek(fs, fd, 0, SPIFFS_SEEK_CUR) will thus return current offset.
* @param fs the file system struct
* @param fh the filehandle
* @param offs how much/where to move the offset
* @param whence if SPIFFS_SEEK_SET, the file offset shall be set to offset bytes
* if SPIFFS_SEEK_CUR, the file offset shall be set to its current location plus offset
* if SPIFFS_SEEK_END, the file offset shall be set to the size of the file plus offse, which should be negative
*/
s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence);
/**
* Removes a file by path
* @param fs the file system struct
* @param path the path of the file to remove
*/
s32_t SPIFFS_remove(spiffs *fs, const char *path);
/**
* Removes a file by filehandle
* @param fs the file system struct
* @param fh the filehandle of the file to remove
*/
s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh);
/**
* Gets file status by path
* @param fs the file system struct
* @param path the path of the file to stat
* @param s the stat struct to populate
*/
s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s);
/**
* Gets file status by filehandle
* @param fs the file system struct
* @param fh the filehandle of the file to stat
* @param s the stat struct to populate
*/
s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s);
/**
* Flushes all pending write operations from cache for given file
* @param fs the file system struct
* @param fh the filehandle of the file to flush
*/
s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh);
/**
* Closes a filehandle. If there are pending write operations, these are finalized before closing.
* @param fs the file system struct
* @param fh the filehandle of the file to close
*/
s32_t SPIFFS_close(spiffs *fs, spiffs_file fh);
/**
* Renames a file
* @param fs the file system struct
* @param old path of file to rename
* @param newPath new path of file
*/
s32_t SPIFFS_rename(spiffs *fs, const char *old, const char *newPath);
#if SPIFFS_OBJ_META_LEN
/**
* Updates file's metadata
* @param fs the file system struct
* @param path path to the file
* @param meta new metadata. must be SPIFFS_OBJ_META_LEN bytes long.
*/
s32_t SPIFFS_update_meta(spiffs *fs, const char *name, const void *meta);
/**
* Updates file's metadata
* @param fs the file system struct
* @param fh file handle of the file
* @param meta new metadata. must be SPIFFS_OBJ_META_LEN bytes long.
*/
s32_t SPIFFS_fupdate_meta(spiffs *fs, spiffs_file fh, const void *meta);
#endif
/**
* Returns last error of last file operation.
* @param fs the file system struct
*/
s32_t SPIFFS_errno(spiffs *fs);
/**
* Clears last error.
* @param fs the file system struct
*/
void SPIFFS_clearerr(spiffs *fs);
/**
* Opens a directory stream corresponding to the given name.
* The stream is positioned at the first entry in the directory.
* On hydrogen builds the name argument is ignored as hydrogen builds always correspond
* to a flat file structure - no directories.
* @param fs the file system struct
* @param name the name of the directory
* @param d pointer the directory stream to be populated
*/
spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d);
/**
* Closes a directory stream
* @param d the directory stream to close
*/
s32_t SPIFFS_closedir(spiffs_DIR *d);
/**
* Reads a directory into given spifs_dirent struct.
* @param d pointer to the directory stream
* @param e the dirent struct to be populated
* @returns null if error or end of stream, else given dirent is returned
*/
struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e);
/**
* Runs a consistency check on given filesystem.
* @param fs the file system struct
*/
s32_t SPIFFS_check(spiffs *fs);
/**
* Returns number of total bytes available and number of used bytes.
* This is an estimation, and depends on if there a many files with little
* data or few files with much data.
* NB: If used number of bytes exceeds total bytes, a SPIFFS_check should
* run. This indicates a power loss in midst of things. In worst case
* (repeated powerlosses in mending or gc) you might have to delete some files.
*
* @param fs the file system struct
* @param total total number of bytes in filesystem
* @param used used number of bytes in filesystem
*/
s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used);
/**
* Formats the entire file system. All data will be lost.
* The filesystem must not be mounted when calling this.
*
* NB: formatting is awkward. Due to backwards compatibility, SPIFFS_mount
* MUST be called prior to formatting in order to configure the filesystem.
* If SPIFFS_mount succeeds, SPIFFS_unmount must be called before calling
* SPIFFS_format.
* If SPIFFS_mount fails, SPIFFS_format can be called directly without calling
* SPIFFS_unmount first.
*
* @param fs the file system struct
*/
s32_t SPIFFS_format(spiffs *fs);
/**
* Returns nonzero if spiffs is mounted, or zero if unmounted.
* @param fs the file system struct
*/
u8_t SPIFFS_mounted(spiffs *fs);
/**
* Tries to find a block where most or all pages are deleted, and erase that
* block if found. Does not care for wear levelling. Will not move pages
* around.
* If parameter max_free_pages are set to 0, only blocks with only deleted
* pages will be selected.
*
* NB: the garbage collector is automatically called when spiffs needs free
* pages. The reason for this function is to give possibility to do background
* tidying when user knows the system is idle.
*
* Use with care.
*
* Setting max_free_pages to anything larger than zero will eventually wear
* flash more as a block containing free pages can be erased.
*
* Will set err_no to SPIFFS_OK if a block was found and erased,
* SPIFFS_ERR_NO_DELETED_BLOCK if no matching block was found,
* or other error.
*
* @param fs the file system struct
* @param max_free_pages maximum number allowed free pages in block
*/
s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages);
/**
* Will try to make room for given amount of bytes in the filesystem by moving
* pages and erasing blocks.
* If it is physically impossible, err_no will be set to SPIFFS_ERR_FULL. If
* there already is this amount (or more) of free space, SPIFFS_gc will
* silently return. It is recommended to call SPIFFS_info before invoking
* this method in order to determine what amount of bytes to give.
*
* NB: the garbage collector is automatically called when spiffs needs free
* pages. The reason for this function is to give possibility to do background
* tidying when user knows the system is idle.
*
* Use with care.
*
* @param fs the file system struct
* @param size amount of bytes that should be freed
*/
s32_t SPIFFS_gc(spiffs *fs, u32_t size);
/**
* Check if EOF reached.
* @param fs the file system struct
* @param fh the filehandle of the file to check
*/
s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh);
/**
* Get position in file.
* @param fs the file system struct
* @param fh the filehandle of the file to check
*/
s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh);
/**
* Registers a callback function that keeps track on operations on file
* headers. Do note, that this callback is called from within internal spiffs
* mechanisms. Any operations on the actual file system being callbacked from
* in this callback will mess things up for sure - do not do this.
* This can be used to track where files are and move around during garbage
* collection, which in turn can be used to build location tables in ram.
* Used in conjuction with SPIFFS_open_by_page this may improve performance
* when opening a lot of files.
* Must be invoked after mount.
*
* @param fs the file system struct
* @param cb_func the callback on file operations
*/
s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func);
#if SPIFFS_IX_MAP
/**
* Maps the first level index lookup to a given memory map.
* This will make reading big files faster, as the memory map will be used for
* looking up data pages instead of searching for the indices on the physical
* medium. When mapping, all affected indicies are found and the information is
* copied to the array.
* Whole file or only parts of it may be mapped. The index map will cover file
* contents from argument offset until and including arguments (offset+len).
* It is valid to map a longer range than the current file size. The map will
* then be populated when the file grows.
* On garbage collections and file data page movements, the map array will be
* automatically updated. Do not tamper with the map array, as this contains
* the references to the data pages. Modifying it from outside will corrupt any
* future readings using this file descriptor.
* The map will no longer be used when the file descriptor closed or the file
* is unmapped.
* This can be useful to get faster and more deterministic timing when reading
* large files, or when seeking and reading a lot within a file.
* @param fs the file system struct
* @param fh the file handle of the file to map
* @param map a spiffs_ix_map struct, describing the index map
* @param offset absolute file offset where to start the index map
* @param len length of the mapping in actual file bytes
* @param map_buf the array buffer for the look up data - number of required
* elements in the array can be derived from function
* SPIFFS_bytes_to_ix_map_entries given the length
*/
s32_t SPIFFS_ix_map(spiffs *fs, spiffs_file fh, spiffs_ix_map *map,
u32_t offset, u32_t len, spiffs_page_ix *map_buf);
/**
* Unmaps the index lookup from this filehandle. All future readings will
* proceed as normal, requiring reading of the first level indices from
* physical media.
* The map and map buffer given in function SPIFFS_ix_map will no longer be
* referenced by spiffs.
* It is not strictly necessary to unmap a file before closing it, as closing
* a file will automatically unmap it.
* @param fs the file system struct
* @param fh the file handle of the file to unmap
*/
s32_t SPIFFS_ix_unmap(spiffs *fs, spiffs_file fh);
/**
* Moves the offset for the index map given in function SPIFFS_ix_map. Parts or
* all of the map buffer will repopulated.
* @param fs the file system struct
* @param fh the mapped file handle of the file to remap
* @param offset new absolute file offset where to start the index map
*/
s32_t SPIFFS_ix_remap(spiffs *fs, spiffs_file fh, u32_t offs);
/**
* Utility function to get number of spiffs_page_ix entries a map buffer must
* contain on order to map given amount of file data in bytes.
* See function SPIFFS_ix_map and SPIFFS_ix_map_entries_to_bytes.
* @param fs the file system struct
* @param bytes number of file data bytes to map
* @return needed number of elements in a spiffs_page_ix array needed to
* map given amount of bytes in a file
*/
s32_t SPIFFS_bytes_to_ix_map_entries(spiffs *fs, u32_t bytes);
/**
* Utility function to amount of file data bytes that can be mapped when
* mapping a file with buffer having given number of spiffs_page_ix entries.
* See function SPIFFS_ix_map and SPIFFS_bytes_to_ix_map_entries.
* @param fs the file system struct
* @param map_page_ix_entries number of entries in a spiffs_page_ix array
* @return amount of file data in bytes that can be mapped given a map
* buffer having given amount of spiffs_page_ix entries
*/
s32_t SPIFFS_ix_map_entries_to_bytes(spiffs *fs, u32_t map_page_ix_entries);
#endif // SPIFFS_IX_MAP
#if SPIFFS_TEST_VISUALISATION
/**
* Prints out a visualization of the filesystem.
* @param fs the file system struct
*/
s32_t SPIFFS_vis(spiffs *fs);
#endif
#if SPIFFS_BUFFER_HELP
/**
* Returns number of bytes needed for the filedescriptor buffer given
* amount of file descriptors.
*/
u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs);
#if SPIFFS_CACHE
/**
* Returns number of bytes needed for the cache buffer given
* amount of cache pages.
*/
u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages);
#endif
#endif
#if SPIFFS_CACHE
#endif
#if defined(__cplusplus)
}
#endif
#endif /* SPIFFS_H_ */

View file

@ -0,0 +1,842 @@
/*
* spiffs_nucleus.h
*
* Created on: Jun 15, 2013
* Author: petera
*/
/* SPIFFS layout
*
* spiffs is designed for following spi flash characteristics:
* - only big areas of data (blocks) can be erased
* - erasing resets all bits in a block to ones
* - writing pulls ones to zeroes
* - zeroes cannot be pulled to ones, without erase
* - wear leveling
*
* spiffs is also meant to be run on embedded, memory constraint devices.
*
* Entire area is divided in blocks. Entire area is also divided in pages.
* Each block contains same number of pages. A page cannot be erased, but a
* block can be erased.
*
* Entire area must be block_size * x
* page_size must be block_size / (2^y) where y > 2
*
* ex: area = 1024*1024 bytes, block size = 65536 bytes, page size = 256 bytes
*
* BLOCK 0 PAGE 0 object lookup 1
* PAGE 1 object lookup 2
* ...
* PAGE n-1 object lookup n
* PAGE n object data 1
* PAGE n+1 object data 2
* ...
* PAGE n+m-1 object data m
*
* BLOCK 1 PAGE n+m object lookup 1
* PAGE n+m+1 object lookup 2
* ...
* PAGE 2n+m-1 object lookup n
* PAGE 2n+m object data 1
* PAGE 2n+m object data 2
* ...
* PAGE 2n+2m-1 object data m
* ...
*
* n is number of object lookup pages, which is number of pages needed to index all pages
* in a block by object id
* : block_size / page_size * sizeof(obj_id) / page_size
* m is number data pages, which is number of pages in block minus number of lookup pages
* : block_size / page_size - block_size / page_size * sizeof(obj_id) / page_size
* thus, n+m is total number of pages in a block
* : block_size / page_size
*
* ex: n = 65536/256*2/256 = 2, m = 65536/256 - 2 = 254 => n+m = 65536/256 = 256
*
* Object lookup pages contain object id entries. Each entry represent the corresponding
* data page.
* Assuming a 16 bit object id, an object id being 0xffff represents a free page.
* An object id being 0x0000 represents a deleted page.
*
* ex: page 0 : lookup : 0008 0001 0aaa ffff ffff ffff ffff ffff ..
* page 1 : lookup : ffff ffff ffff ffff ffff ffff ffff ffff ..
* page 2 : data : data for object id 0008
* page 3 : data : data for object id 0001
* page 4 : data : data for object id 0aaa
* ...
*
*
* Object data pages can be either object index pages or object content.
* All object data pages contains a data page header, containing object id and span index.
* The span index denotes the object page ordering amongst data pages with same object id.
* This applies to both object index pages (when index spans more than one page of entries),
* and object data pages.
* An object index page contains page entries pointing to object content page. The entry index
* in a object index page correlates to the span index in the actual object data page.
* The first object index page (span index 0) is called object index header page, and also
* contains object flags (directory/file), size, object name etc.
*
* ex:
* BLOCK 1
* PAGE 256: objectl lookup page 1
* [*123] [ 123] [ 123] [ 123]
* [ 123] [*123] [ 123] [ 123]
* [free] [free] [free] [free] ...
* PAGE 257: objectl lookup page 2
* [free] [free] [free] [free] ...
* PAGE 258: object index page (header)
* obj.id:0123 span.ix:0000 flags:INDEX
* size:1600 name:ex.txt type:file
* [259] [260] [261] [262]
* PAGE 259: object data page
* obj.id:0123 span.ix:0000 flags:DATA
* PAGE 260: object data page
* obj.id:0123 span.ix:0001 flags:DATA
* PAGE 261: object data page
* obj.id:0123 span.ix:0002 flags:DATA
* PAGE 262: object data page
* obj.id:0123 span.ix:0003 flags:DATA
* PAGE 263: object index page
* obj.id:0123 span.ix:0001 flags:INDEX
* [264] [265] [fre] [fre]
* [fre] [fre] [fre] [fre]
* PAGE 264: object data page
* obj.id:0123 span.ix:0004 flags:DATA
* PAGE 265: object data page
* obj.id:0123 span.ix:0005 flags:DATA
*
*/
#ifndef SPIFFS_NUCLEUS_H_
#define SPIFFS_NUCLEUS_H_
#define _SPIFFS_ERR_CHECK_FIRST (SPIFFS_ERR_INTERNAL - 1)
#define SPIFFS_ERR_CHECK_OBJ_ID_MISM (SPIFFS_ERR_INTERNAL - 1)
#define SPIFFS_ERR_CHECK_SPIX_MISM (SPIFFS_ERR_INTERNAL - 2)
#define SPIFFS_ERR_CHECK_FLAGS_BAD (SPIFFS_ERR_INTERNAL - 3)
#define _SPIFFS_ERR_CHECK_LAST (SPIFFS_ERR_INTERNAL - 4)
// visitor result, continue searching
#define SPIFFS_VIS_COUNTINUE (SPIFFS_ERR_INTERNAL - 20)
// visitor result, continue searching after reloading lu buffer
#define SPIFFS_VIS_COUNTINUE_RELOAD (SPIFFS_ERR_INTERNAL - 21)
// visitor result, stop searching
#define SPIFFS_VIS_END (SPIFFS_ERR_INTERNAL - 22)
// updating an object index contents
#define SPIFFS_EV_IX_UPD (0)
// creating a new object index
#define SPIFFS_EV_IX_NEW (1)
// deleting an object index
#define SPIFFS_EV_IX_DEL (2)
// moving an object index without updating contents
#define SPIFFS_EV_IX_MOV (3)
// updating an object index header data only, not the table itself
#define SPIFFS_EV_IX_UPD_HDR (4)
#define SPIFFS_OBJ_ID_IX_FLAG ((spiffs_obj_id)(1<<(8*sizeof(spiffs_obj_id)-1)))
#define SPIFFS_UNDEFINED_LEN (u32_t)(-1)
#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1)
#if defined(__GNUC__) || defined(__clang__) || defined(__TI_COMPILER_VERSION__)
/* For GCC, clang and TI compilers */
#define SPIFFS_PACKED __attribute__((packed))
#elif defined(__ICCARM__) || defined(__CC_ARM)
/* For IAR ARM and Keil MDK-ARM compilers */
#define SPIFFS_PACKED
#else
/* Unknown compiler */
#define SPIFFS_PACKED
#endif
#if SPIFFS_USE_MAGIC
#if !SPIFFS_USE_MAGIC_LENGTH
#define SPIFFS_MAGIC(fs, bix) \
((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs)))
#else // SPIFFS_USE_MAGIC_LENGTH
#define SPIFFS_MAGIC(fs, bix) \
((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs) ^ ((fs)->block_count - (bix))))
#endif // SPIFFS_USE_MAGIC_LENGTH
#endif // SPIFFS_USE_MAGIC
#define SPIFFS_CONFIG_MAGIC (0x20090315)
#if SPIFFS_SINGLETON == 0
#define SPIFFS_CFG_LOG_PAGE_SZ(fs) \
((fs)->cfg.log_page_size)
#define SPIFFS_CFG_LOG_BLOCK_SZ(fs) \
((fs)->cfg.log_block_size)
#define SPIFFS_CFG_PHYS_SZ(fs) \
((fs)->cfg.phys_size)
#define SPIFFS_CFG_PHYS_ERASE_SZ(fs) \
((fs)->cfg.phys_erase_block)
#define SPIFFS_CFG_PHYS_ADDR(fs) \
((fs)->cfg.phys_addr)
#endif
// total number of pages
#define SPIFFS_MAX_PAGES(fs) \
( SPIFFS_CFG_PHYS_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) )
// total number of pages per block, including object lookup pages
#define SPIFFS_PAGES_PER_BLOCK(fs) \
( SPIFFS_CFG_LOG_BLOCK_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) )
// number of object lookup pages per block
#define SPIFFS_OBJ_LOOKUP_PAGES(fs) \
(MAX(1, (SPIFFS_PAGES_PER_BLOCK(fs) * sizeof(spiffs_obj_id)) / SPIFFS_CFG_LOG_PAGE_SZ(fs)) )
// checks if page index belongs to object lookup
#define SPIFFS_IS_LOOKUP_PAGE(fs,pix) \
(((pix) % SPIFFS_PAGES_PER_BLOCK(fs)) < SPIFFS_OBJ_LOOKUP_PAGES(fs))
// number of object lookup entries in all object lookup pages
#define SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) \
(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))
// converts a block to physical address
#define SPIFFS_BLOCK_TO_PADDR(fs, block) \
( SPIFFS_CFG_PHYS_ADDR(fs) + (block)* SPIFFS_CFG_LOG_BLOCK_SZ(fs) )
// converts a object lookup entry to page index
#define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, block, entry) \
((block)*SPIFFS_PAGES_PER_BLOCK(fs) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry))
// converts a object lookup entry to physical address of corresponding page
#define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, block, entry) \
(SPIFFS_BLOCK_TO_PADDR(fs, block) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry) * SPIFFS_CFG_LOG_PAGE_SZ(fs) )
// converts a page to physical address
#define SPIFFS_PAGE_TO_PADDR(fs, page) \
( SPIFFS_CFG_PHYS_ADDR(fs) + (page) * SPIFFS_CFG_LOG_PAGE_SZ(fs) )
// converts a physical address to page
#define SPIFFS_PADDR_TO_PAGE(fs, addr) \
( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) / SPIFFS_CFG_LOG_PAGE_SZ(fs) )
// gives index in page for a physical address
#define SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr) \
( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) % SPIFFS_CFG_LOG_PAGE_SZ(fs) )
// returns containing block for given page
#define SPIFFS_BLOCK_FOR_PAGE(fs, page) \
( (page) / SPIFFS_PAGES_PER_BLOCK(fs) )
// returns starting page for block
#define SPIFFS_PAGE_FOR_BLOCK(fs, block) \
( (block) * SPIFFS_PAGES_PER_BLOCK(fs) )
// converts page to entry in object lookup page
#define SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, page) \
( (page) % SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) )
// returns data size in a data page
#define SPIFFS_DATA_PAGE_SIZE(fs) \
( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) )
// returns physical address for block's erase count,
// always in the physical last entry of the last object lookup page
#define SPIFFS_ERASE_COUNT_PADDR(fs, bix) \
( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id) )
// returns physical address for block's magic,
// always in the physical second last entry of the last object lookup page
#define SPIFFS_MAGIC_PADDR(fs, bix) \
( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id)*2 )
// checks if there is any room for magic in the object luts
#define SPIFFS_CHECK_MAGIC_POSSIBLE(fs) \
( (SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) % (SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(spiffs_obj_id))) * sizeof(spiffs_obj_id) \
<= (SPIFFS_CFG_LOG_PAGE_SZ(fs)-sizeof(spiffs_obj_id)*2) )
// define helpers object
// entries in an object header page index
#define SPIFFS_OBJ_HDR_IX_LEN(fs) \
((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header))/sizeof(spiffs_page_ix))
// entries in an object page index
#define SPIFFS_OBJ_IX_LEN(fs) \
((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix))/sizeof(spiffs_page_ix))
// object index entry for given data span index
#define SPIFFS_OBJ_IX_ENTRY(fs, spix) \
((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? (spix) : (((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))%SPIFFS_OBJ_IX_LEN(fs)))
// object index span index number for given data span index or entry
#define SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, spix) \
((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? 0 : (1+((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))/SPIFFS_OBJ_IX_LEN(fs)))
// get data span index for object index span index
#define SPIFFS_DATA_SPAN_IX_FOR_OBJ_IX_SPAN_IX(fs, spix) \
( (spix) == 0 ? 0 : (SPIFFS_OBJ_HDR_IX_LEN(fs) + (((spix)-1) * SPIFFS_OBJ_IX_LEN(fs))) )
#if SPIFFS_FILEHDL_OFFSET
#define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0)
#define SPIFFS_FH_UNOFFS(fs, fh) ((fh) != 0 ? ((fh) - (fs)->cfg.fh_ix_offset) : 0)
#else
#define SPIFFS_FH_OFFS(fs, fh) (fh)
#define SPIFFS_FH_UNOFFS(fs, fh) (fh)
#endif
#define SPIFFS_OP_T_OBJ_LU (0<<0)
#define SPIFFS_OP_T_OBJ_LU2 (1<<0)
#define SPIFFS_OP_T_OBJ_IX (2<<0)
#define SPIFFS_OP_T_OBJ_DA (3<<0)
#define SPIFFS_OP_C_DELE (0<<2)
#define SPIFFS_OP_C_UPDT (1<<2)
#define SPIFFS_OP_C_MOVS (2<<2)
#define SPIFFS_OP_C_MOVD (3<<2)
#define SPIFFS_OP_C_FLSH (4<<2)
#define SPIFFS_OP_C_READ (5<<2)
#define SPIFFS_OP_C_WRTHRU (6<<2)
#define SPIFFS_OP_TYPE_MASK (3<<0)
#define SPIFFS_OP_COM_MASK (7<<2)
// if 0, this page is written to, else clean
#define SPIFFS_PH_FLAG_USED (1<<0)
// if 0, writing is finalized, else under modification
#define SPIFFS_PH_FLAG_FINAL (1<<1)
// if 0, this is an index page, else a data page
#define SPIFFS_PH_FLAG_INDEX (1<<2)
// if 0, page is deleted, else valid
#define SPIFFS_PH_FLAG_DELET (1<<7)
// if 0, this index header is being deleted
#define SPIFFS_PH_FLAG_IXDELE (1<<6)
#define SPIFFS_CHECK_MOUNT(fs) \
((fs)->mounted != 0)
#define SPIFFS_CHECK_CFG(fs) \
((fs)->config_magic == SPIFFS_CONFIG_MAGIC)
#define SPIFFS_CHECK_RES(res) \
do { \
if ((res) < SPIFFS_OK) return (res); \
} while (0);
#define SPIFFS_API_CHECK_MOUNT(fs) \
if (!SPIFFS_CHECK_MOUNT((fs))) { \
(fs)->err_code = SPIFFS_ERR_NOT_MOUNTED; \
return SPIFFS_ERR_NOT_MOUNTED; \
}
#define SPIFFS_API_CHECK_CFG(fs) \
if (!SPIFFS_CHECK_CFG((fs))) { \
(fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; \
return SPIFFS_ERR_NOT_CONFIGURED; \
}
#define SPIFFS_API_CHECK_RES(fs, res) \
if ((res) < SPIFFS_OK) { \
(fs)->err_code = (res); \
return (res); \
}
#define SPIFFS_API_CHECK_RES_UNLOCK(fs, res) \
if ((res) < SPIFFS_OK) { \
(fs)->err_code = (res); \
SPIFFS_UNLOCK(fs); \
return (res); \
}
#define SPIFFS_VALIDATE_OBJIX(ph, objid, spix) \
if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \
if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \
if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \
if (((ph).flags & SPIFFS_PH_FLAG_INDEX) != 0) return SPIFFS_ERR_NOT_INDEX; \
if (((objid) & SPIFFS_OBJ_ID_IX_FLAG) == 0) return SPIFFS_ERR_NOT_INDEX; \
if ((ph).span_ix != (spix)) return SPIFFS_ERR_INDEX_SPAN_MISMATCH;
//if ((spix) == 0 && ((ph).flags & SPIFFS_PH_FLAG_IXDELE) == 0) return SPIFFS_ERR_DELETED;
#define SPIFFS_VALIDATE_DATA(ph, objid, spix) \
if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \
if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \
if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \
if (((ph).flags & SPIFFS_PH_FLAG_INDEX) == 0) return SPIFFS_ERR_IS_INDEX; \
if ((objid) & SPIFFS_OBJ_ID_IX_FLAG) return SPIFFS_ERR_IS_INDEX; \
if ((ph).span_ix != (spix)) return SPIFFS_ERR_DATA_SPAN_MISMATCH;
// check id, only visit matching objec ids
#define SPIFFS_VIS_CHECK_ID (1<<0)
// report argument object id to visitor - else object lookup id is reported
#define SPIFFS_VIS_CHECK_PH (1<<1)
// stop searching at end of all look up pages
#define SPIFFS_VIS_NO_WRAP (1<<2)
#if SPIFFS_HAL_CALLBACK_EXTRA
#define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \
(_fs)->cfg.hal_write_f((_fs), (_paddr), (_len), (_src))
#define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \
(_fs)->cfg.hal_read_f((_fs), (_paddr), (_len), (_dst))
#define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \
(_fs)->cfg.hal_erase_f((_fs), (_paddr), (_len))
#else // SPIFFS_HAL_CALLBACK_EXTRA
#define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \
(_fs)->cfg.hal_write_f((_paddr), (_len), (_src))
#define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \
(_fs)->cfg.hal_read_f((_paddr), (_len), (_dst))
#define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \
(_fs)->cfg.hal_erase_f((_paddr), (_len))
#endif // SPIFFS_HAL_CALLBACK_EXTRA
#if SPIFFS_CACHE
#define SPIFFS_CACHE_FLAG_DIRTY (1<<0)
#define SPIFFS_CACHE_FLAG_WRTHRU (1<<1)
#define SPIFFS_CACHE_FLAG_OBJLU (1<<2)
#define SPIFFS_CACHE_FLAG_OBJIX (1<<3)
#define SPIFFS_CACHE_FLAG_DATA (1<<4)
#define SPIFFS_CACHE_FLAG_TYPE_WR (1<<7)
#define SPIFFS_CACHE_PAGE_SIZE(fs) \
(sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs))
#define spiffs_get_cache(fs) \
((spiffs_cache *)((fs)->cache))
#define spiffs_get_cache_page_hdr(fs, c, ix) \
((spiffs_cache_page *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)])))
#define spiffs_get_cache_page(fs, c, ix) \
((u8_t *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)])) + sizeof(spiffs_cache_page))
// cache page struct
typedef struct {
// cache flags
u8_t flags;
// cache page index
u8_t ix;
// last access of this cache page
u32_t last_access;
union {
// type read cache
struct {
// read cache page index
spiffs_page_ix pix;
};
#if SPIFFS_CACHE_WR
// type write cache
struct {
// write cache
spiffs_obj_id obj_id;
// offset in cache page
u32_t offset;
// size of cache page
u16_t size;
};
#endif
};
} spiffs_cache_page;
// cache struct
typedef struct {
u8_t cpage_count;
u32_t last_access;
u32_t cpage_use_map;
u32_t cpage_use_mask;
u8_t *cpages;
} spiffs_cache;
#endif
// spiffs nucleus file descriptor
typedef struct {
// the filesystem of this descriptor
spiffs *fs;
// number of file descriptor - if 0, the file descriptor is closed
spiffs_file file_nbr;
// object id - if SPIFFS_OBJ_ID_ERASED, the file was deleted
spiffs_obj_id obj_id;
// size of the file
u32_t size;
// cached object index header page index
spiffs_page_ix objix_hdr_pix;
// cached offset object index page index
spiffs_page_ix cursor_objix_pix;
// cached offset object index span index
spiffs_span_ix cursor_objix_spix;
// current absolute offset
u32_t offset;
// current file descriptor offset (cached)
u32_t fdoffset;
// fd flags
spiffs_flags flags;
#if SPIFFS_CACHE_WR
spiffs_cache_page *cache_page;
#endif
#if SPIFFS_TEMPORAL_FD_CACHE
// djb2 hash of filename
u32_t name_hash;
// hit score (score == 0 indicates never used fd)
u16_t score;
#endif
#if SPIFFS_IX_MAP
// spiffs index map, if 0 it means unmapped
spiffs_ix_map *ix_map;
#endif
} spiffs_fd;
// object structs
// page header, part of each page except object lookup pages
// NB: this is always aligned when the data page is an object index,
// as in this case struct spiffs_page_object_ix is used
typedef struct SPIFFS_PACKED {
// object id
spiffs_obj_id obj_id;
// object span index
spiffs_span_ix span_ix;
// flags
u8_t flags;
} spiffs_page_header;
// object index header page header
typedef struct SPIFFS_PACKED
#if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
__attribute(( aligned(sizeof(spiffs_page_ix)) ))
#endif
{
// common page header
spiffs_page_header p_hdr;
// alignment
u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))];
// size of object
u32_t size;
// type of object
spiffs_obj_type type;
// name of object
u8_t name[SPIFFS_OBJ_NAME_LEN];
#if SPIFFS_OBJ_META_LEN
// metadata. not interpreted by SPIFFS in any way.
u8_t meta[SPIFFS_OBJ_META_LEN];
#endif
} spiffs_page_object_ix_header;
// object index page header
typedef struct SPIFFS_PACKED {
spiffs_page_header p_hdr;
u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))];
} spiffs_page_object_ix;
// callback func for object lookup visitor
typedef s32_t (*spiffs_visitor_f)(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry,
const void *user_const_p, void *user_var_p);
#if SPIFFS_CACHE
#define _spiffs_rd(fs, op, fh, addr, len, dst) \
spiffs_phys_rd((fs), (op), (fh), (addr), (len), (dst))
#define _spiffs_wr(fs, op, fh, addr, len, src) \
spiffs_phys_wr((fs), (op), (fh), (addr), (len), (src))
#else
#define _spiffs_rd(fs, op, fh, addr, len, dst) \
spiffs_phys_rd((fs), (addr), (len), (dst))
#define _spiffs_wr(fs, op, fh, addr, len, src) \
spiffs_phys_wr((fs), (addr), (len), (src))
#endif
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
// ---------------
s32_t spiffs_phys_rd(
spiffs *fs,
#if SPIFFS_CACHE
u8_t op,
spiffs_file fh,
#endif
u32_t addr,
u32_t len,
u8_t *dst);
s32_t spiffs_phys_wr(
spiffs *fs,
#if SPIFFS_CACHE
u8_t op,
spiffs_file fh,
#endif
u32_t addr,
u32_t len,
u8_t *src);
s32_t spiffs_phys_cpy(
spiffs *fs,
spiffs_file fh,
u32_t dst,
u32_t src,
u32_t len);
s32_t spiffs_phys_count_free_blocks(
spiffs *fs);
s32_t spiffs_obj_lu_find_entry_visitor(
spiffs *fs,
spiffs_block_ix starting_block,
int starting_lu_entry,
u8_t flags,
spiffs_obj_id obj_id,
spiffs_visitor_f v,
const void *user_const_p,
void *user_var_p,
spiffs_block_ix *block_ix,
int *lu_entry);
s32_t spiffs_erase_block(
spiffs *fs,
spiffs_block_ix bix);
#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
s32_t spiffs_probe(
spiffs_config *cfg);
#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH
// ---------------
s32_t spiffs_obj_lu_scan(
spiffs *fs);
s32_t spiffs_obj_lu_find_free_obj_id(
spiffs *fs,
spiffs_obj_id *obj_id,
const u8_t *conflicting_name);
s32_t spiffs_obj_lu_find_free(
spiffs *fs,
spiffs_block_ix starting_block,
int starting_lu_entry,
spiffs_block_ix *block_ix,
int *lu_entry);
s32_t spiffs_obj_lu_find_id(
spiffs *fs,
spiffs_block_ix starting_block,
int starting_lu_entry,
spiffs_obj_id obj_id,
spiffs_block_ix *block_ix,
int *lu_entry);
s32_t spiffs_obj_lu_find_id_and_span(
spiffs *fs,
spiffs_obj_id obj_id,
spiffs_span_ix spix,
spiffs_page_ix exclusion_pix,
spiffs_page_ix *pix);
s32_t spiffs_obj_lu_find_id_and_span_by_phdr(
spiffs *fs,
spiffs_obj_id obj_id,
spiffs_span_ix spix,
spiffs_page_ix exclusion_pix,
spiffs_page_ix *pix);
// ---------------
s32_t spiffs_page_allocate_data(
spiffs *fs,
spiffs_obj_id obj_id,
spiffs_page_header *ph,
u8_t *data,
u32_t len,
u32_t page_offs,
u8_t finalize,
spiffs_page_ix *pix);
s32_t spiffs_page_move(
spiffs *fs,
spiffs_file fh,
u8_t *page_data,
spiffs_obj_id obj_id,
spiffs_page_header *page_hdr,
spiffs_page_ix src_pix,
spiffs_page_ix *dst_pix);
s32_t spiffs_page_delete(
spiffs *fs,
spiffs_page_ix pix);
// ---------------
s32_t spiffs_object_create(
spiffs *fs,
spiffs_obj_id obj_id,
const u8_t name[],
const u8_t meta[],
spiffs_obj_type type,
spiffs_page_ix *objix_hdr_pix);
s32_t spiffs_object_update_index_hdr(
spiffs *fs,
spiffs_fd *fd,
spiffs_obj_id obj_id,
spiffs_page_ix objix_hdr_pix,
u8_t *new_objix_hdr_data,
const u8_t name[],
const u8_t meta[],
u32_t size,
spiffs_page_ix *new_pix);
#if SPIFFS_IX_MAP
s32_t spiffs_populate_ix_map(
spiffs *fs,
spiffs_fd *fd,
u32_t vec_entry_start,
u32_t vec_entry_end);
#endif
void spiffs_cb_object_event(
spiffs *fs,
spiffs_page_object_ix *objix,
int ev,
spiffs_obj_id obj_id,
spiffs_span_ix spix,
spiffs_page_ix new_pix,
u32_t new_size);
s32_t spiffs_object_open_by_id(
spiffs *fs,
spiffs_obj_id obj_id,
spiffs_fd *f,
spiffs_flags flags,
spiffs_mode mode);
s32_t spiffs_object_open_by_page(
spiffs *fs,
spiffs_page_ix pix,
spiffs_fd *f,
spiffs_flags flags,
spiffs_mode mode);
s32_t spiffs_object_append(
spiffs_fd *fd,
u32_t offset,
u8_t *data,
u32_t len);
s32_t spiffs_object_modify(
spiffs_fd *fd,
u32_t offset,
u8_t *data,
u32_t len);
s32_t spiffs_object_read(
spiffs_fd *fd,
u32_t offset,
u32_t len,
u8_t *dst);
s32_t spiffs_object_truncate(
spiffs_fd *fd,
u32_t new_len,
u8_t remove_object);
s32_t spiffs_object_find_object_index_header_by_name(
spiffs *fs,
const u8_t name[SPIFFS_OBJ_NAME_LEN],
spiffs_page_ix *pix);
// ---------------
s32_t spiffs_gc_check(
spiffs *fs,
u32_t len);
s32_t spiffs_gc_erase_page_stats(
spiffs *fs,
spiffs_block_ix bix);
s32_t spiffs_gc_find_candidate(
spiffs *fs,
spiffs_block_ix **block_candidate,
int *candidate_count,
char fs_crammed);
s32_t spiffs_gc_clean(
spiffs *fs,
spiffs_block_ix bix);
s32_t spiffs_gc_quick(
spiffs *fs, u16_t max_free_pages);
// ---------------
s32_t spiffs_fd_find_new(
spiffs *fs,
spiffs_fd **fd,
const char *name);
s32_t spiffs_fd_return(
spiffs *fs,
spiffs_file f);
s32_t spiffs_fd_get(
spiffs *fs,
spiffs_file f,
spiffs_fd **fd);
#if SPIFFS_TEMPORAL_FD_CACHE
void spiffs_fd_temporal_cache_rehash(
spiffs *fs,
const char *old_path,
const char *new_path);
#endif
#if SPIFFS_CACHE
void spiffs_cache_init(
spiffs *fs);
void spiffs_cache_drop_page(
spiffs *fs,
spiffs_page_ix pix);
#if SPIFFS_CACHE_WR
spiffs_cache_page *spiffs_cache_page_allocate_by_fd(
spiffs *fs,
spiffs_fd *fd);
void spiffs_cache_fd_release(
spiffs *fs,
spiffs_cache_page *cp);
spiffs_cache_page *spiffs_cache_page_get_by_fd(
spiffs *fs,
spiffs_fd *fd);
#endif
#endif
s32_t spiffs_lookup_consistency_check(
spiffs *fs,
u8_t check_all_objects);
s32_t spiffs_page_consistency_check(
spiffs *fs);
s32_t spiffs_object_index_consistency_check(
spiffs *fs);
// memcpy macro,
// checked in test builds, otherwise plain memcpy (unless already defined)
#ifdef _SPIFFS_TEST
#define _SPIFFS_MEMCPY(__d, __s, __l) do { \
intptr_t __a1 = (intptr_t)((u8_t*)(__s)); \
intptr_t __a2 = (intptr_t)((u8_t*)(__s)+(__l)); \
intptr_t __b1 = (intptr_t)((u8_t*)(__d)); \
intptr_t __b2 = (intptr_t)((u8_t*)(__d)+(__l)); \
if (__a1 <= __b2 && __b1 <= __a2) { \
printf("FATAL OVERLAP: memcpy from %lx..%lx to %lx..%lx\n", __a1, __a2, __b1, __b2); \
ERREXIT(); \
} \
memcpy((__d),(__s),(__l)); \
} while (0)
#else
#ifndef _SPIFFS_MEMCPY
#define _SPIFFS_MEMCPY(__d, __s, __l) do{memcpy((__d),(__s),(__l));}while(0)
#endif
#endif //_SPIFFS_TEST
#endif /* SPIFFS_NUCLEUS_H_ */

View file

@ -0,0 +1,319 @@
/*
* spiffs_cache.c
*
* Created on: Jun 23, 2013
* Author: petera
*/
#include "spiffs.h"
#include "spiffs_nucleus.h"
#if SPIFFS_CACHE
// returns cached page for give page index, or null if no such cached page
static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix) {
spiffs_cache *cache = spiffs_get_cache(fs);
if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) return 0;
int i;
for (i = 0; i < cache->cpage_count; i++) {
spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i);
if ((cache->cpage_use_map & (1<<i)) &&
(cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 &&
cp->pix == pix ) {
//SPIFFS_CACHE_DBG("CACHE_GET: have cache page "_SPIPRIi" for "_SPIPRIpg"\n", i, pix);
cp->last_access = cache->last_access;
return cp;
}
}
//SPIFFS_CACHE_DBG("CACHE_GET: no cache for "_SPIPRIpg"\n", pix);
return 0;
}
// frees cached page
static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) {
s32_t res = SPIFFS_OK;
spiffs_cache *cache = spiffs_get_cache(fs);
spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, ix);
if (cache->cpage_use_map & (1<<ix)) {
if (write_back &&
(cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 &&
(cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) {
u8_t *mem = spiffs_get_cache_page(fs, cache, ix);
SPIFFS_CACHE_DBG("CACHE_FREE: write cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix);
res = SPIFFS_HAL_WRITE(fs, SPIFFS_PAGE_TO_PADDR(fs, cp->pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem);
}
#if SPIFFS_CACHE_WR
if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) {
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" objid "_SPIPRIid"\n", ix, cp->obj_id);
} else
#endif
{
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page "_SPIPRIi" pix "_SPIPRIpg"\n", ix, cp->pix);
}
cache->cpage_use_map &= ~(1 << ix);
cp->flags = 0;
}
return res;
}
// removes the oldest accessed cached page
static s32_t spiffs_cache_page_remove_oldest(spiffs *fs, u8_t flag_mask, u8_t flags) {
s32_t res = SPIFFS_OK;
spiffs_cache *cache = spiffs_get_cache(fs);
if ((cache->cpage_use_map & cache->cpage_use_mask) != cache->cpage_use_mask) {
// at least one free cpage
return SPIFFS_OK;
}
// all busy, scan thru all to find the cpage which has oldest access
int i;
int cand_ix = -1;
u32_t oldest_val = 0;
for (i = 0; i < cache->cpage_count; i++) {
spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i);
if ((cache->last_access - cp->last_access) > oldest_val &&
(cp->flags & flag_mask) == flags) {
oldest_val = cache->last_access - cp->last_access;
cand_ix = i;
}
}
if (cand_ix >= 0) {
res = spiffs_cache_page_free(fs, cand_ix, 1);
}
return res;
}
// allocates a new cached page and returns it, or null if all cache pages are busy
static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) {
spiffs_cache *cache = spiffs_get_cache(fs);
if (cache->cpage_use_map == 0xffffffff) {
// out of cache memory
return 0;
}
int i;
for (i = 0; i < cache->cpage_count; i++) {
if ((cache->cpage_use_map & (1<<i)) == 0) {
spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i);
cache->cpage_use_map |= (1<<i);
cp->last_access = cache->last_access;
//SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi"\n", i);
return cp;
}
}
// out of cache entries
return 0;
}
// drops the cache page for give page index
void spiffs_cache_drop_page(spiffs *fs, spiffs_page_ix pix) {
spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix);
if (cp) {
spiffs_cache_page_free(fs, cp->ix, 0);
}
}
// ------------------------------
// reads from spi flash or the cache
s32_t spiffs_phys_rd(
spiffs *fs,
u8_t op,
spiffs_file fh,
u32_t addr,
u32_t len,
u8_t *dst) {
(void)fh;
s32_t res = SPIFFS_OK;
spiffs_cache *cache = spiffs_get_cache(fs);
spiffs_cache_page *cp = spiffs_cache_page_get(fs, SPIFFS_PADDR_TO_PAGE(fs, addr));
cache->last_access++;
if (cp) {
// we've already got one, you see
#if SPIFFS_CACHE_STATS
fs->cache_hits++;
#endif
cp->last_access = cache->last_access;
u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix);
_SPIFFS_MEMCPY(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len);
} else {
if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) {
// for second layer lookup functions, we do not cache in order to prevent shredding
return SPIFFS_HAL_READ(fs, addr, len, dst);
}
#if SPIFFS_CACHE_STATS
fs->cache_misses++;
#endif
// this operation will always free one cache page (unless all already free),
// the result code stems from the write operation of the possibly freed cache page
res = spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0);
cp = spiffs_cache_page_allocate(fs);
if (cp) {
cp->flags = SPIFFS_CACHE_FLAG_WRTHRU;
cp->pix = SPIFFS_PADDR_TO_PAGE(fs, addr);
SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for pix "_SPIPRIpg "\n", cp->ix, cp->pix);
s32_t res2 = SPIFFS_HAL_READ(fs,
addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr),
SPIFFS_CFG_LOG_PAGE_SZ(fs),
spiffs_get_cache_page(fs, cache, cp->ix));
if (res2 != SPIFFS_OK) {
// honor read failure before possible write failure (bad idea?)
res = res2;
}
u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix);
_SPIFFS_MEMCPY(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len);
} else {
// this will never happen, last resort for sake of symmetry
s32_t res2 = SPIFFS_HAL_READ(fs, addr, len, dst);
if (res2 != SPIFFS_OK) {
// honor read failure before possible write failure (bad idea?)
res = res2;
}
}
}
return res;
}
// writes to spi flash and/or the cache
s32_t spiffs_phys_wr(
spiffs *fs,
u8_t op,
spiffs_file fh,
u32_t addr,
u32_t len,
u8_t *src) {
(void)fh;
spiffs_page_ix pix = SPIFFS_PADDR_TO_PAGE(fs, addr);
spiffs_cache *cache = spiffs_get_cache(fs);
spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix);
if (cp && (op & SPIFFS_OP_COM_MASK) != SPIFFS_OP_C_WRTHRU) {
// have a cache page
// copy in data to cache page
if ((op & SPIFFS_OP_COM_MASK) == SPIFFS_OP_C_DELE &&
(op & SPIFFS_OP_TYPE_MASK) != SPIFFS_OP_T_OBJ_LU) {
// page is being deleted, wipe from cache - unless it is a lookup page
spiffs_cache_page_free(fs, cp->ix, 0);
return SPIFFS_HAL_WRITE(fs, addr, len, src);
}
u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix);
_SPIFFS_MEMCPY(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len);
cache->last_access++;
cp->last_access = cache->last_access;
if (cp->flags & SPIFFS_CACHE_FLAG_WRTHRU) {
// page is being updated, no write-cache, just pass thru
return SPIFFS_HAL_WRITE(fs, addr, len, src);
} else {
return SPIFFS_OK;
}
} else {
// no cache page, no write cache - just write thru
return SPIFFS_HAL_WRITE(fs, addr, len, src);
}
}
#if SPIFFS_CACHE_WR
// returns the cache page that this fd refers, or null if no cache page
spiffs_cache_page *spiffs_cache_page_get_by_fd(spiffs *fs, spiffs_fd *fd) {
spiffs_cache *cache = spiffs_get_cache(fs);
if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) {
// all cpages free, no cpage cannot be assigned to obj_id
return 0;
}
int i;
for (i = 0; i < cache->cpage_count; i++) {
spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i);
if ((cache->cpage_use_map & (1<<i)) &&
(cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) &&
cp->obj_id == fd->obj_id) {
return cp;
}
}
return 0;
}
// allocates a new cache page and refers this to given fd - flushes an old cache
// page if all cache is busy
spiffs_cache_page *spiffs_cache_page_allocate_by_fd(spiffs *fs, spiffs_fd *fd) {
// before this function is called, it is ensured that there is no already existing
// cache page with same object id
spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0);
spiffs_cache_page *cp = spiffs_cache_page_allocate(fs);
if (cp == 0) {
// could not get cache page
return 0;
}
cp->flags = SPIFFS_CACHE_FLAG_TYPE_WR;
cp->obj_id = fd->obj_id;
fd->cache_page = cp;
SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page "_SPIPRIi" for fd "_SPIPRIfd ":"_SPIPRIid "\n", cp->ix, fd->file_nbr, fd->obj_id);
return cp;
}
// unrefers all fds that this cache page refers to and releases the cache page
void spiffs_cache_fd_release(spiffs *fs, spiffs_cache_page *cp) {
if (cp == 0) return;
u32_t i;
spiffs_fd *fds = (spiffs_fd *)fs->fd_space;
for (i = 0; i < fs->fd_count; i++) {
spiffs_fd *cur_fd = &fds[i];
if (cur_fd->file_nbr != 0 && cur_fd->cache_page == cp) {
cur_fd->cache_page = 0;
}
}
spiffs_cache_page_free(fs, cp->ix, 0);
cp->obj_id = 0;
}
#endif
// initializes the cache
void spiffs_cache_init(spiffs *fs) {
if (fs->cache == 0) return;
u32_t sz = fs->cache_size;
u32_t cache_mask = 0;
int i;
int cache_entries =
(sz - sizeof(spiffs_cache)) / (SPIFFS_CACHE_PAGE_SIZE(fs));
if (cache_entries <= 0) return;
for (i = 0; i < cache_entries; i++) {
cache_mask <<= 1;
cache_mask |= 1;
}
spiffs_cache cache;
memset(&cache, 0, sizeof(spiffs_cache));
cache.cpage_count = cache_entries;
cache.cpages = (u8_t *)((u8_t *)fs->cache + sizeof(spiffs_cache));
cache.cpage_use_map = 0xffffffff;
cache.cpage_use_mask = cache_mask;
_SPIFFS_MEMCPY(fs->cache, &cache, sizeof(spiffs_cache));
spiffs_cache *c = spiffs_get_cache(fs);
memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs));
c->cpage_use_map &= ~(c->cpage_use_mask);
for (i = 0; i < cache.cpage_count; i++) {
spiffs_get_cache_page_hdr(fs, c, i)->ix = i;
}
}
#endif // SPIFFS_CACHE

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,606 @@
#include "spiffs.h"
#include "spiffs_nucleus.h"
#if !SPIFFS_READ_ONLY
// Erases a logical block and updates the erase counter.
// If cache is enabled, all pages that might be cached in this block
// is dropped.
static s32_t spiffs_gc_erase_block(
spiffs *fs,
spiffs_block_ix bix) {
s32_t res;
SPIFFS_GC_DBG("gc: erase block "_SPIPRIbl"\n", bix);
res = spiffs_erase_block(fs, bix);
SPIFFS_CHECK_RES(res);
#if SPIFFS_CACHE
{
u32_t i;
for (i = 0; i < SPIFFS_PAGES_PER_BLOCK(fs); i++) {
spiffs_cache_drop_page(fs, SPIFFS_PAGE_FOR_BLOCK(fs, bix) + i);
}
}
#endif
return res;
}
// Searches for blocks where all entries are deleted - if one is found,
// the block is erased. Compared to the non-quick gc, the quick one ensures
// that no updates are needed on existing objects on pages that are erased.
s32_t spiffs_gc_quick(
spiffs *fs, u16_t max_free_pages) {
s32_t res = SPIFFS_OK;
u32_t blocks = fs->block_count;
spiffs_block_ix cur_block = 0;
u32_t cur_block_addr = 0;
int cur_entry = 0;
spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work;
SPIFFS_GC_DBG("gc_quick: running\n");
#if SPIFFS_GC_STATS
fs->stats_gc_runs++;
#endif
int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
// find fully deleted blocks
// check each block
while (res == SPIFFS_OK && blocks--) {
u16_t deleted_pages_in_block = 0;
u16_t free_pages_in_block = 0;
int obj_lookup_page = 0;
// check each object lookup page
while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
int entry_offset = obj_lookup_page * entries_per_page;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
// check each entry
while (res == SPIFFS_OK &&
cur_entry - entry_offset < entries_per_page &&
cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) {
spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset];
if (obj_id == SPIFFS_OBJ_ID_DELETED) {
deleted_pages_in_block++;
} else if (obj_id == SPIFFS_OBJ_ID_FREE) {
// kill scan, go for next block
free_pages_in_block++;
if (free_pages_in_block > max_free_pages) {
obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs);
res = 1; // kill object lu loop
break;
}
} else {
// kill scan, go for next block
obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs);
res = 1; // kill object lu loop
break;
}
cur_entry++;
} // per entry
obj_lookup_page++;
} // per object lookup page
if (res == 1) res = SPIFFS_OK;
if (res == SPIFFS_OK &&
deleted_pages_in_block + free_pages_in_block == SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs) &&
free_pages_in_block <= max_free_pages) {
// found a fully deleted block
fs->stats_p_deleted -= deleted_pages_in_block;
res = spiffs_gc_erase_block(fs, cur_block);
return res;
}
cur_entry = 0;
cur_block++;
cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs);
} // per block
if (res == SPIFFS_OK) {
res = SPIFFS_ERR_NO_DELETED_BLOCKS;
}
return res;
}
// Checks if garbage collecting is necessary. If so a candidate block is found,
// cleansed and erased
s32_t spiffs_gc_check(
spiffs *fs,
u32_t len) {
s32_t res;
s32_t free_pages =
(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count-2)
- fs->stats_p_allocated - fs->stats_p_deleted;
int tries = 0;
if (fs->free_blocks > 3 &&
(s32_t)len < free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) {
return SPIFFS_OK;
}
u32_t needed_pages = (len + SPIFFS_DATA_PAGE_SIZE(fs) - 1) / SPIFFS_DATA_PAGE_SIZE(fs);
// if (fs->free_blocks <= 2 && (s32_t)needed_pages > free_pages) {
// SPIFFS_GC_DBG("gc: full freeblk:"_SPIPRIi" needed:"_SPIPRIi" free:"_SPIPRIi" dele:"_SPIPRIi"\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted);
// return SPIFFS_ERR_FULL;
// }
if ((s32_t)needed_pages > (s32_t)(free_pages + fs->stats_p_deleted)) {
SPIFFS_GC_DBG("gc_check: full freeblk:"_SPIPRIi" needed:"_SPIPRIi" free:"_SPIPRIi" dele:"_SPIPRIi"\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted);
return SPIFFS_ERR_FULL;
}
do {
SPIFFS_GC_DBG("\ngc_check #"_SPIPRIi": run gc free_blocks:"_SPIPRIi" pfree:"_SPIPRIi" pallo:"_SPIPRIi" pdele:"_SPIPRIi" ["_SPIPRIi"] len:"_SPIPRIi" of "_SPIPRIi"\n",
tries,
fs->free_blocks, free_pages, fs->stats_p_allocated, fs->stats_p_deleted, (free_pages+fs->stats_p_allocated+fs->stats_p_deleted),
len, (u32_t)(free_pages*SPIFFS_DATA_PAGE_SIZE(fs)));
spiffs_block_ix *cands;
int count;
spiffs_block_ix cand;
s32_t prev_free_pages = free_pages;
// if the fs is crammed, ignore block age when selecting candidate - kind of a bad state
res = spiffs_gc_find_candidate(fs, &cands, &count, free_pages <= 0);
SPIFFS_CHECK_RES(res);
if (count == 0) {
SPIFFS_GC_DBG("gc_check: no candidates, return\n");
return (s32_t)needed_pages < free_pages ? SPIFFS_OK : SPIFFS_ERR_FULL;
}
#if SPIFFS_GC_STATS
fs->stats_gc_runs++;
#endif
cand = cands[0];
fs->cleaning = 1;
//SPIFFS_GC_DBG("gcing: cleaning block "_SPIPRIi"\n", cand);
res = spiffs_gc_clean(fs, cand);
fs->cleaning = 0;
if (res < 0) {
SPIFFS_GC_DBG("gc_check: cleaning block "_SPIPRIi", result "_SPIPRIi"\n", cand, res);
} else {
SPIFFS_GC_DBG("gc_check: cleaning block "_SPIPRIi", result "_SPIPRIi"\n", cand, res);
}
SPIFFS_CHECK_RES(res);
res = spiffs_gc_erase_page_stats(fs, cand);
SPIFFS_CHECK_RES(res);
res = spiffs_gc_erase_block(fs, cand);
SPIFFS_CHECK_RES(res);
free_pages =
(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2)
- fs->stats_p_allocated - fs->stats_p_deleted;
if (prev_free_pages <= 0 && prev_free_pages == free_pages) {
// abort early to reduce wear, at least tried once
SPIFFS_GC_DBG("gc_check: early abort, no result on gc when fs crammed\n");
break;
}
} while (++tries < SPIFFS_GC_MAX_RUNS && (fs->free_blocks <= 2 ||
(s32_t)len > free_pages*(s32_t)SPIFFS_DATA_PAGE_SIZE(fs)));
free_pages =
(SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2)
- fs->stats_p_allocated - fs->stats_p_deleted;
if ((s32_t)len > free_pages*(s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) {
res = SPIFFS_ERR_FULL;
}
SPIFFS_GC_DBG("gc_check: finished, "_SPIPRIi" dirty, blocks "_SPIPRIi" free, "_SPIPRIi" pages free, "_SPIPRIi" tries, res "_SPIPRIi"\n",
fs->stats_p_allocated + fs->stats_p_deleted,
fs->free_blocks, free_pages, tries, res);
return res;
}
// Updates page statistics for a block that is about to be erased
s32_t spiffs_gc_erase_page_stats(
spiffs *fs,
spiffs_block_ix bix) {
s32_t res = SPIFFS_OK;
int obj_lookup_page = 0;
int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work;
int cur_entry = 0;
u32_t dele = 0;
u32_t allo = 0;
// check each object lookup page
while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
int entry_offset = obj_lookup_page * entries_per_page;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
// check each entry
while (res == SPIFFS_OK &&
cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) {
spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset];
if (obj_id == SPIFFS_OBJ_ID_FREE) {
} else if (obj_id == SPIFFS_OBJ_ID_DELETED) {
dele++;
} else {
allo++;
}
cur_entry++;
} // per entry
obj_lookup_page++;
} // per object lookup page
SPIFFS_GC_DBG("gc_check: wipe pallo:"_SPIPRIi" pdele:"_SPIPRIi"\n", allo, dele);
fs->stats_p_allocated -= allo;
fs->stats_p_deleted -= dele;
return res;
}
// Finds block candidates to erase
s32_t spiffs_gc_find_candidate(
spiffs *fs,
spiffs_block_ix **block_candidates,
int *candidate_count,
char fs_crammed) {
s32_t res = SPIFFS_OK;
u32_t blocks = fs->block_count;
spiffs_block_ix cur_block = 0;
u32_t cur_block_addr = 0;
spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work;
int cur_entry = 0;
// using fs->work area as sorted candidate memory, (spiffs_block_ix)cand_bix/(s32_t)score
int max_candidates = MIN(fs->block_count, (SPIFFS_CFG_LOG_PAGE_SZ(fs)-8)/(sizeof(spiffs_block_ix) + sizeof(s32_t)));
*candidate_count = 0;
memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs));
// divide up work area into block indices and scores
spiffs_block_ix *cand_blocks = (spiffs_block_ix *)fs->work;
s32_t *cand_scores = (s32_t *)(fs->work + max_candidates * sizeof(spiffs_block_ix));
// align cand_scores on s32_t boundary
cand_scores = (s32_t*)(((intptr_t)cand_scores + sizeof(intptr_t) - 1) & ~(sizeof(intptr_t) - 1));
*block_candidates = cand_blocks;
int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
// check each block
while (res == SPIFFS_OK && blocks--) {
u16_t deleted_pages_in_block = 0;
u16_t used_pages_in_block = 0;
int obj_lookup_page = 0;
// check each object lookup page
while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
int entry_offset = obj_lookup_page * entries_per_page;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
// check each entry
while (res == SPIFFS_OK &&
cur_entry - entry_offset < entries_per_page &&
cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) {
spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset];
if (obj_id == SPIFFS_OBJ_ID_FREE) {
// when a free entry is encountered, scan logic ensures that all following entries are free also
res = 1; // kill object lu loop
break;
} else if (obj_id == SPIFFS_OBJ_ID_DELETED) {
deleted_pages_in_block++;
} else {
used_pages_in_block++;
}
cur_entry++;
} // per entry
obj_lookup_page++;
} // per object lookup page
if (res == 1) res = SPIFFS_OK;
// calculate score and insert into candidate table
// stoneage sort, but probably not so many blocks
if (res == SPIFFS_OK /*&& deleted_pages_in_block > 0*/) {
// read erase count
spiffs_obj_id erase_count;
res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0,
SPIFFS_ERASE_COUNT_PADDR(fs, cur_block),
sizeof(spiffs_obj_id), (u8_t *)&erase_count);
SPIFFS_CHECK_RES(res);
spiffs_obj_id erase_age;
if (fs->max_erase_count > erase_count) {
erase_age = fs->max_erase_count - erase_count;
} else {
erase_age = SPIFFS_OBJ_ID_FREE - (erase_count - fs->max_erase_count);
}
s32_t score =
deleted_pages_in_block * SPIFFS_GC_HEUR_W_DELET +
used_pages_in_block * SPIFFS_GC_HEUR_W_USED +
erase_age * (fs_crammed ? 0 : SPIFFS_GC_HEUR_W_ERASE_AGE);
int cand_ix = 0;
SPIFFS_GC_DBG("gc_check: bix:"_SPIPRIbl" del:"_SPIPRIi" use:"_SPIPRIi" score:"_SPIPRIi"\n", cur_block, deleted_pages_in_block, used_pages_in_block, score);
while (cand_ix < max_candidates) {
if (cand_blocks[cand_ix] == (spiffs_block_ix)-1) {
cand_blocks[cand_ix] = cur_block;
cand_scores[cand_ix] = score;
break;
} else if (cand_scores[cand_ix] < score) {
int reorder_cand_ix = max_candidates - 2;
while (reorder_cand_ix >= cand_ix) {
cand_blocks[reorder_cand_ix + 1] = cand_blocks[reorder_cand_ix];
cand_scores[reorder_cand_ix + 1] = cand_scores[reorder_cand_ix];
reorder_cand_ix--;
}
cand_blocks[cand_ix] = cur_block;
cand_scores[cand_ix] = score;
break;
}
cand_ix++;
}
(*candidate_count)++;
}
cur_entry = 0;
cur_block++;
cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs);
} // per block
return res;
}
typedef enum {
FIND_OBJ_DATA,
MOVE_OBJ_DATA,
MOVE_OBJ_IX,
FINISHED
} spiffs_gc_clean_state;
typedef struct {
spiffs_gc_clean_state state;
spiffs_obj_id cur_obj_id;
spiffs_span_ix cur_objix_spix;
spiffs_page_ix cur_objix_pix;
spiffs_page_ix cur_data_pix;
int stored_scan_entry_index;
u8_t obj_id_found;
} spiffs_gc;
// Empties given block by moving all data into free pages of another block
// Strategy:
// loop:
// scan object lookup for object data pages
// for first found id, check spix and load corresponding object index page to memory
// push object scan lookup entry index
// rescan object lookup, find data pages with same id and referenced by same object index
// move data page, update object index in memory
// when reached end of lookup, store updated object index
// pop object scan lookup entry index
// repeat loop until end of object lookup
// scan object lookup again for remaining object index pages, move to new page in other block
//
s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) {
s32_t res = SPIFFS_OK;
const int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
// this is the global localizer being pushed and popped
int cur_entry = 0;
spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work;
spiffs_gc gc; // our stack frame/state
spiffs_page_ix cur_pix = 0;
spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work;
spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work;
SPIFFS_GC_DBG("gc_clean: cleaning block "_SPIPRIbl"\n", bix);
memset(&gc, 0, sizeof(spiffs_gc));
gc.state = FIND_OBJ_DATA;
if (fs->free_cursor_block_ix == bix) {
// move free cursor to next block, cannot use free pages from the block we want to clean
fs->free_cursor_block_ix = (bix+1)%fs->block_count;
fs->free_cursor_obj_lu_entry = 0;
SPIFFS_GC_DBG("gc_clean: move free cursor to block "_SPIPRIbl"\n", fs->free_cursor_block_ix);
}
while (res == SPIFFS_OK && gc.state != FINISHED) {
SPIFFS_GC_DBG("gc_clean: state = "_SPIPRIi" entry:"_SPIPRIi"\n", gc.state, cur_entry);
gc.obj_id_found = 0; // reset (to no found data page)
// scan through lookup pages
int obj_lookup_page = cur_entry / entries_per_page;
u8_t scan = 1;
// check each object lookup page
while (scan && res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
int entry_offset = obj_lookup_page * entries_per_page;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page),
SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
// check each object lookup entry
while (scan && res == SPIFFS_OK &&
cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) {
spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset];
cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, cur_entry);
// act upon object id depending on gc state
switch (gc.state) {
case FIND_OBJ_DATA:
// find a data page
if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE &&
((obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0)) {
// found a data page, stop scanning and handle in switch case below
SPIFFS_GC_DBG("gc_clean: FIND_DATA state:"_SPIPRIi" - found obj id "_SPIPRIid"\n", gc.state, obj_id);
gc.obj_id_found = 1;
gc.cur_obj_id = obj_id;
gc.cur_data_pix = cur_pix;
scan = 0;
}
break;
case MOVE_OBJ_DATA:
// evacuate found data pages for corresponding object index we have in memory,
// update memory representation
if (obj_id == gc.cur_obj_id) {
spiffs_page_header p_hdr;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr);
SPIFFS_CHECK_RES(res);
SPIFFS_GC_DBG("gc_clean: MOVE_DATA found data page "_SPIPRIid":"_SPIPRIsp" @ "_SPIPRIpg"\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix);
if (SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix) != gc.cur_objix_spix) {
SPIFFS_GC_DBG("gc_clean: MOVE_DATA no objix spix match, take in another run\n");
} else {
spiffs_page_ix new_data_pix;
if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) {
// move page
res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_data_pix);
SPIFFS_GC_DBG("gc_clean: MOVE_DATA move objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg" to "_SPIPRIpg"\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix, new_data_pix);
SPIFFS_CHECK_RES(res);
// move wipes obj_lu, reload it
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page),
SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
SPIFFS_CHECK_RES(res);
} else {
// page is deleted but not deleted in lookup, scrap it -
// might seem unnecessary as we will erase this block, but
// we might get aborted
SPIFFS_GC_DBG("gc_clean: MOVE_DATA wipe objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix);
res = spiffs_page_delete(fs, cur_pix);
SPIFFS_CHECK_RES(res);
new_data_pix = SPIFFS_OBJ_ID_FREE;
}
// update memory representation of object index page with new data page
if (gc.cur_objix_spix == 0) {
// update object index header page
((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[p_hdr.span_ix] = new_data_pix;
SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page "_SPIPRIpg" to objix_hdr entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix));
} else {
// update object index page
((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)] = new_data_pix;
SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page "_SPIPRIpg" to objix entry "_SPIPRIsp" in mem\n", new_data_pix, (spiffs_span_ix)SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix));
}
}
}
break;
case MOVE_OBJ_IX:
// find and evacuate object index pages
if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE &&
(obj_id & SPIFFS_OBJ_ID_IX_FLAG)) {
// found an index object id
spiffs_page_header p_hdr;
spiffs_page_ix new_pix;
// load header
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr);
SPIFFS_CHECK_RES(res);
if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) {
// move page
res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_pix);
SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX move objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg" to "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix, new_pix);
SPIFFS_CHECK_RES(res);
spiffs_cb_object_event(fs, (spiffs_page_object_ix *)&p_hdr,
SPIFFS_EV_IX_MOV, obj_id, p_hdr.span_ix, new_pix, 0);
// move wipes obj_lu, reload it
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page),
SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
SPIFFS_CHECK_RES(res);
} else {
// page is deleted but not deleted in lookup, scrap it -
// might seem unnecessary as we will erase this block, but
// we might get aborted
SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX wipe objix "_SPIPRIid":"_SPIPRIsp" page "_SPIPRIpg"\n", obj_id, p_hdr.span_ix, cur_pix);
res = spiffs_page_delete(fs, cur_pix);
if (res == SPIFFS_OK) {
spiffs_cb_object_event(fs, (spiffs_page_object_ix *)0,
SPIFFS_EV_IX_DEL, obj_id, p_hdr.span_ix, cur_pix, 0);
}
}
SPIFFS_CHECK_RES(res);
}
break;
default:
scan = 0;
break;
} // switch gc state
cur_entry++;
} // per entry
obj_lookup_page++; // no need to check scan variable here, obj_lookup_page is set in start of loop
} // per object lookup page
if (res != SPIFFS_OK) break;
// state finalization and switch
switch (gc.state) {
case FIND_OBJ_DATA:
if (gc.obj_id_found) {
// handle found data page -
// find out corresponding obj ix page and load it to memory
spiffs_page_header p_hdr;
spiffs_page_ix objix_pix;
gc.stored_scan_entry_index = cur_entry; // push cursor
cur_entry = 0; // restart scan from start
gc.state = MOVE_OBJ_DATA;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr);
SPIFFS_CHECK_RES(res);
gc.cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix);
SPIFFS_GC_DBG("gc_clean: FIND_DATA find objix span_ix:"_SPIPRIsp"\n", gc.cur_objix_spix);
res = spiffs_obj_lu_find_id_and_span(fs, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix, 0, &objix_pix);
if (res == SPIFFS_ERR_NOT_FOUND) {
// on borked systems we might get an ERR_NOT_FOUND here -
// this is handled by simply deleting the page as it is not referenced
// from anywhere
SPIFFS_GC_DBG("gc_clean: FIND_OBJ_DATA objix not found! Wipe page "_SPIPRIpg"\n", gc.cur_data_pix);
res = spiffs_page_delete(fs, gc.cur_data_pix);
SPIFFS_CHECK_RES(res);
// then we restore states and continue scanning for data pages
cur_entry = gc.stored_scan_entry_index; // pop cursor
gc.state = FIND_OBJ_DATA;
break; // done
}
SPIFFS_CHECK_RES(res);
SPIFFS_GC_DBG("gc_clean: FIND_DATA found object index at page "_SPIPRIpg"\n", objix_pix);
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work);
SPIFFS_CHECK_RES(res);
// cannot allow a gc if the presumed index in fact is no index, a
// check must run or lot of data may be lost
SPIFFS_VALIDATE_OBJIX(objix->p_hdr, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix);
gc.cur_objix_pix = objix_pix;
} else {
// no more data pages found, passed thru all block, start evacuating object indices
gc.state = MOVE_OBJ_IX;
cur_entry = 0; // restart entry scan index
}
break;
case MOVE_OBJ_DATA: {
// store modified objix (hdr) page residing in memory now that all
// data pages belonging to this object index and residing in the block
// we want to evacuate
spiffs_page_ix new_objix_pix;
gc.state = FIND_OBJ_DATA;
cur_entry = gc.stored_scan_entry_index; // pop cursor
if (gc.cur_objix_spix == 0) {
// store object index header page
res = spiffs_object_update_index_hdr(fs, 0, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_pix, fs->work, 0, 0, 0, &new_objix_pix);
SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix_hdr page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, 0);
SPIFFS_CHECK_RES(res);
} else {
// store object index page
res = spiffs_page_move(fs, 0, fs->work, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, gc.cur_objix_pix, &new_objix_pix);
SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix page, "_SPIPRIpg":"_SPIPRIsp"\n", new_objix_pix, objix->p_hdr.span_ix);
SPIFFS_CHECK_RES(res);
spiffs_cb_object_event(fs, (spiffs_page_object_ix *)fs->work,
SPIFFS_EV_IX_UPD, gc.cur_obj_id, objix->p_hdr.span_ix, new_objix_pix, 0);
}
}
break;
case MOVE_OBJ_IX:
// scanned thru all block, no more object indices found - our work here is done
gc.state = FINISHED;
break;
default:
cur_entry = 0;
break;
} // switch gc.state
SPIFFS_GC_DBG("gc_clean: state-> "_SPIPRIi"\n", gc.state);
} // while state != FINISHED
return res;
}
#endif // !SPIFFS_READ_ONLY

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,548 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include "spiffs_config.h"
#include "spiffs.h"
#include "spiffs_nucleus.h"
#include <hal/hal.h>
#include <vfs_inode.h>
#include <vfs_register.h>
static const char* spiffs_mnt_path = "/spiffs";
typedef struct {
spiffs *fs;
aos_mutex_t lock;
spiffs_config *cfg;
uint8_t *work;
uint32_t work_sz;
uint8_t *fds;
uint32_t fds_sz;
#if SPIFFS_CACHE
uint8_t *cache;
uint32_t cache_sz;
#endif
} spiffs_mgr_t;
typedef struct {
aos_dir_t dir;
spiffs_DIR d;
aos_dirent_t cur_dirent;
}spiffs_dir_t;
static spiffs_mgr_t *g_spiffs_mgr = NULL;
static int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst)
{
return hal_flash_read((hal_partition_t)SPIFFS_CFG_PARTITION, &addr, dst, size);
}
static int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *dst)
{
return hal_flash_write((hal_partition_t)SPIFFS_CFG_PARTITION, &addr, dst, size);
}
static int32_t spiffs_hal_erase(uint32_t addr, uint32_t size)
{
return hal_flash_erase((hal_partition_t)SPIFFS_CFG_PARTITION, addr, size);
}
void _spiffs_lock(spiffs *fs)
{
aos_mutex_lock(&(((spiffs_mgr_t *)(fs->user_data))->lock), AOS_WAIT_FOREVER);
}
void _spiffs_unlock(spiffs *fs)
{
aos_mutex_unlock(&(((spiffs_mgr_t *)(fs->user_data))->lock));
}
static char* translate_relative_path(const char *path)
{
int len, prefix_len;
char *relpath, *p;
if (!path)
return NULL;
len = strlen(path);
prefix_len = strlen(spiffs_mnt_path);
if (strncmp(spiffs_mnt_path, path, prefix_len) != 0)
return NULL;
len = len - prefix_len;
relpath = (char *)aos_malloc(len + 1);
if (!relpath)
return NULL;
memset(relpath, 0, len + 1);
if (len > 0) {
p = (char *)(path + prefix_len + 1);
memcpy(relpath, p, len - 1);
}
relpath[len] = '\0';
return relpath;
}
static int _spiffs_ret_to_err(int ret)
{
switch (ret) {
case SPIFFS_OK:
return 0;
case SPIFFS_ERR_NOT_MOUNTED:
case SPIFFS_ERR_NOT_A_FS:
return -ENODEV;
case SPIFFS_ERR_FULL:
return -ENOSPC;
case SPIFFS_ERR_BAD_DESCRIPTOR:
return -EBADF;
case SPIFFS_ERR_MOUNTED:
case SPIFFS_ERR_FILE_EXISTS:
return -EEXIST;
case SPIFFS_ERR_NOT_FOUND:
case SPIFFS_ERR_NOT_A_FILE:
case SPIFFS_ERR_DELETED:
case SPIFFS_ERR_FILE_DELETED:
return -ENOENT;
case SPIFFS_ERR_NAME_TOO_LONG:
return -ENAMETOOLONG;
case SPIFFS_ERR_RO_NOT_IMPL:
case SPIFFS_ERR_RO_ABORTED_OPERATION:
return -EROFS;
default:
return EIO;
}
}
static int _spiffs_mode_conv(int flags)
{
int acc_mode, res = 0;
acc_mode = flags & O_ACCMODE;
if (acc_mode == O_RDONLY) {
res |= SPIFFS_O_RDONLY;
} else if (acc_mode == O_WRONLY) {
res |= SPIFFS_O_WRONLY;
} else if (acc_mode == O_RDWR) {
res |= SPIFFS_O_RDWR;
}
if ((flags & O_CREAT) && (flags & O_EXCL)) {
res |= SPIFFS_O_CREAT | SPIFFS_O_EXCL;
} else if ((flags & O_CREAT) && (flags & O_TRUNC)) {
res |= SPIFFS_O_CREAT | SPIFFS_O_TRUNC;
} else if (flags & O_APPEND) {
res |= SPIFFS_O_CREAT | SPIFFS_O_APPEND;
}
return res;
}
static int _spiffs_open(file_t *fp, const char *path, int flags)
{
int fd;
char *relpath = NULL;
relpath = translate_relative_path(path);
if (!relpath)
return -EINVAL;
fd = SPIFFS_open(g_spiffs_mgr->fs, relpath, _spiffs_mode_conv(flags), 0);
if (fd > 0) {
fp->f_arg = (void *)fd;
fd = 0;
} else {
fd = _spiffs_ret_to_err(SPIFFS_errno(g_spiffs_mgr->fs));
SPIFFS_clearerr(g_spiffs_mgr->fs);
}
aos_free(relpath);
return fd;
}
static int _spiffs_close(file_t *fp)
{
int fd;
int ret = SPIFFS_ERR_FILE_CLOSED;
fd = (int)(fp->f_arg);
ret = SPIFFS_close(g_spiffs_mgr->fs, fd);
if (ret < 0) {
ret = _spiffs_ret_to_err(SPIFFS_errno(g_spiffs_mgr->fs));
SPIFFS_clearerr(g_spiffs_mgr->fs);
} else {
fp->f_arg = NULL;
}
return ret;
}
static ssize_t _spiffs_read(file_t *fp, char *buf, size_t len)
{
ssize_t nbytes;
int fd;
fd = (int)(fp->f_arg);
nbytes = SPIFFS_read(g_spiffs_mgr->fs, fd, buf, len);
if (nbytes < 0) {
nbytes = _spiffs_ret_to_err(SPIFFS_errno(g_spiffs_mgr->fs));
SPIFFS_clearerr(g_spiffs_mgr->fs);
}
return nbytes;
}
static ssize_t _spiffs_write(file_t *fp, const char *buf, size_t len)
{
ssize_t nbytes;
int fd;
fd = (int)(fp->f_arg);
nbytes = SPIFFS_write(g_spiffs_mgr->fs, fd, (void *)buf, len);
if (nbytes < 0) {
nbytes = _spiffs_ret_to_err(SPIFFS_errno(g_spiffs_mgr->fs));
SPIFFS_clearerr(g_spiffs_mgr->fs);
}
return nbytes;
}
static off_t _spiffs_lseek(file_t *fp, off_t off, int whence)
{
off_t ret;
int fd;
fd = (int)(fp->f_arg);
ret = SPIFFS_lseek(g_spiffs_mgr->fs, fd, off, whence);
if (ret < 0) {
ret = _spiffs_ret_to_err(SPIFFS_errno(g_spiffs_mgr->fs));
SPIFFS_clearerr(g_spiffs_mgr->fs);
}
return ret;
}
static int _spiffs_sync(file_t *fp)
{
int ret, fd;
fd = (int)(fp->f_arg);
ret = SPIFFS_fflush(g_spiffs_mgr->fs, fd);
if (ret < 0) {
ret = _spiffs_ret_to_err(SPIFFS_errno(g_spiffs_mgr->fs));
SPIFFS_clearerr(g_spiffs_mgr->fs);
} else {
ret = 0;
}
return ret;
}
static int _spiffs_stat(file_t *fp, const char *path, struct stat *st)
{
int ret;
spiffs_stat s;
char *relpath = NULL;
relpath = translate_relative_path(path);
if (!relpath)
return -EINVAL;
ret = SPIFFS_stat(g_spiffs_mgr->fs, relpath, &s);
if (ret < 0) {
ret = _spiffs_ret_to_err(SPIFFS_errno(g_spiffs_mgr->fs));
SPIFFS_clearerr(g_spiffs_mgr->fs);
} else {
st->st_size = s.size;
st->st_mode = S_IRWXU | S_IRWXG | S_IRWXO |
((s.type == SPIFFS_TYPE_DIR)?S_IFDIR:S_IFREG);
}
aos_free(relpath);
return ret;
}
static int _spiffs_unlink(file_t *fp, const char *path)
{
int ret;
char *relpath = NULL;
relpath = translate_relative_path(path);
if (!relpath)
return -EINVAL;
ret = SPIFFS_remove(g_spiffs_mgr->fs, relpath);
if (ret < 0) {
ret = _spiffs_ret_to_err(SPIFFS_errno(g_spiffs_mgr->fs));
SPIFFS_clearerr(g_spiffs_mgr->fs);
}
aos_free(relpath);
return ret;
}
static int _spiffs_rename(file_t *fp, const char *oldpath, const char *newpath)
{
int ret;
char *oldname = NULL;
char *newname = NULL;
oldname = translate_relative_path(oldpath);
if (!oldname)
return -EINVAL;
newname = translate_relative_path(newpath);
if (!newname) {
aos_free(oldname);
return -EINVAL;
}
ret = SPIFFS_rename(g_spiffs_mgr->fs, oldname, newname);
if (ret < 0) {
ret = _spiffs_ret_to_err(SPIFFS_errno(g_spiffs_mgr->fs));
SPIFFS_clearerr(g_spiffs_mgr->fs);
}
aos_free(oldname);
aos_free(newname);
return ret;
}
static aos_dir_t* _spiffs_opendir(file_t *fp, const char *path)
{
spiffs_dir_t *dp = NULL;
char *relpath = NULL;
relpath = translate_relative_path(path);
if (!relpath)
return NULL;
dp = (spiffs_dir_t *)aos_malloc(sizeof(spiffs_dir_t) + SPIFFS_OBJ_NAME_LEN);
if (!dp) {
aos_free(relpath);
return NULL;
}
memset(dp, 0, sizeof(spiffs_dir_t) + SPIFFS_OBJ_NAME_LEN);
if (!SPIFFS_opendir(g_spiffs_mgr->fs, relpath, &dp->d)) {
aos_free(relpath);
aos_free(dp);
SPIFFS_clearerr(g_spiffs_mgr->fs);
return NULL;
}
aos_free(relpath);
return (aos_dir_t *)dp;
}
static aos_dirent_t* _spiffs_readdir(file_t *fp, aos_dir_t *dir)
{
spiffs_dir_t *dp;
struct spiffs_dirent e;
aos_dirent_t *out_dirent;
dp = (spiffs_dir_t *)dir;
if (!dp)
return NULL;
if (!SPIFFS_readdir(&dp->d, &e)) {
SPIFFS_clearerr(g_spiffs_mgr->fs);
return NULL;
}
if (e.name[0] == 0)
return NULL;
dp->cur_dirent.d_ino = 0;
dp->cur_dirent.d_type = e.type;
strncpy(dp->cur_dirent.d_name, (char *)e.name, SPIFFS_OBJ_NAME_LEN);
dp->cur_dirent.d_name[SPIFFS_OBJ_NAME_LEN] = '\0';
out_dirent = &dp->cur_dirent;
return out_dirent;
}
static int _spiffs_closedir(file_t *fp, aos_dir_t *dir)
{
int ret;
spiffs_dir_t *dp = (spiffs_dir_t *)dir;
if (!dp)
return -EINVAL;
ret = SPIFFS_closedir(&dp->d);
if (ret < 0) {
ret = _spiffs_ret_to_err(SPIFFS_errno(g_spiffs_mgr->fs));
SPIFFS_clearerr(g_spiffs_mgr->fs);
}
aos_free(dp);
return ret;
}
static void _spiffs_deinit(void)
{
if (!g_spiffs_mgr)
return;
if (g_spiffs_mgr->fs) {
SPIFFS_unmount(g_spiffs_mgr->fs);
aos_free(g_spiffs_mgr->fs);
}
#if SPIFFS_CACHE
if (g_spiffs_mgr->cache)
aos_free(g_spiffs_mgr->cache);
#endif
if (g_spiffs_mgr->fds)
aos_free(g_spiffs_mgr->fds);
if (g_spiffs_mgr->work)
aos_free(g_spiffs_mgr->work);
if (g_spiffs_mgr->cfg)
aos_free(g_spiffs_mgr->cfg);
aos_mutex_free(&g_spiffs_mgr->lock);
aos_free(g_spiffs_mgr);
g_spiffs_mgr = NULL;
}
static int _spiffs_init(void)
{
if (g_spiffs_mgr)
return 0;
g_spiffs_mgr = (spiffs_mgr_t *)aos_malloc(sizeof(spiffs_mgr_t));
if (!g_spiffs_mgr)
return -ENOMEM;
memset(g_spiffs_mgr, 0, sizeof(spiffs_mgr_t));
/* init spiffs lock */
if (aos_mutex_new(&g_spiffs_mgr->lock) != 0)
goto err;
/* init spiffs work buffer */
g_spiffs_mgr->work_sz = CFG_SPIFFS_LOG_PAGE_SZ * 2;
g_spiffs_mgr->work = (uint8_t *)aos_malloc(g_spiffs_mgr->work_sz);
if (g_spiffs_mgr->work == NULL)
goto err;
memset(g_spiffs_mgr->work, 0, g_spiffs_mgr->work_sz);
/* init spiffs fds */
g_spiffs_mgr->fds_sz = sizeof(spiffs_fd) * CFG_SPIFFS_MAX_FILES;
g_spiffs_mgr->fds = (uint8_t *)aos_malloc(g_spiffs_mgr->fds_sz);
if (g_spiffs_mgr->fds == NULL)
goto err;
memset(g_spiffs_mgr->fds, 0, g_spiffs_mgr->fds_sz);
#if SPIFFS_CACHE
/* init spiffs cache */
g_spiffs_mgr->cache_sz = sizeof(spiffs_cache) + CFG_SPIFFS_MAX_FILES *
(sizeof(spiffs_cache_page) + CFG_SPIFFS_LOG_PAGE_SZ);
g_spiffs_mgr->cache = (uint8_t *)aos_malloc(g_spiffs_mgr->cache_sz);
if (g_spiffs_mgr->cache == NULL)
goto err;
memset(g_spiffs_mgr->cache, 0, g_spiffs_mgr->cache_sz);
#endif
/* init spiffs config */
g_spiffs_mgr->cfg = (spiffs_config *)aos_malloc(sizeof(spiffs_config));
if (g_spiffs_mgr->cfg == NULL)
goto err;
memset(g_spiffs_mgr->cfg, 0, sizeof(spiffs_config));
g_spiffs_mgr->cfg->hal_read_f = spiffs_hal_read;
g_spiffs_mgr->cfg->hal_write_f = spiffs_hal_write;
g_spiffs_mgr->cfg->hal_erase_f = spiffs_hal_erase;
#if SPIFFS_SINGLETON == 0
g_spiffs_mgr->cfg->phys_size = CFG_SPIFFS_PHYS_SZ;
g_spiffs_mgr->cfg->phys_addr = CFG_SPIFFS_PHYS_ADDR;
g_spiffs_mgr->cfg->phys_erase_block = CFG_SPIFFS_PHYS_ERASE_SZ;
g_spiffs_mgr->cfg->log_block_size = CFG_SPIFFS_LOG_BLOCK_SZ;
g_spiffs_mgr->cfg->log_page_size = CFG_SPIFFS_LOG_PAGE_SZ;
#endif
#if SPIFFS_FILEHDL_OFFSET
g_spiffs_mgr->cfg->fh_ix_offset = SPIFFS_FILEHDL_OFFSET;
#endif
/* init spiffs fs struct */
g_spiffs_mgr->fs = (spiffs *)aos_malloc(sizeof(spiffs));
if (g_spiffs_mgr->fs == NULL)
goto err;
memset(g_spiffs_mgr->fs, 0, sizeof(spiffs));
g_spiffs_mgr->fs->user_data = (void *)g_spiffs_mgr->fs;
return 0;
err:
_spiffs_deinit();
return -1;
}
static const fs_ops_t spiffs_ops = {
.open = &_spiffs_open,
.close = &_spiffs_close,
.read = &_spiffs_read,
.write = &_spiffs_write,
.lseek = &_spiffs_lseek,
.sync = &_spiffs_sync,
.stat = &_spiffs_stat,
.unlink = &_spiffs_unlink,
.rename = &_spiffs_rename,
.opendir = &_spiffs_opendir,
.readdir = &_spiffs_readdir,
.closedir = &_spiffs_closedir,
.mkdir = NULL,
.ioctl = NULL
};
int vfs_spiffs_register(void)
{
int ret = SPIFFS_OK;
ret = _spiffs_init();
if (ret != SPIFFS_OK)
return ret;
// first try to mount
ret = SPIFFS_mount(g_spiffs_mgr->fs, g_spiffs_mgr->cfg,
g_spiffs_mgr->work, g_spiffs_mgr->fds, g_spiffs_mgr->fds_sz,
g_spiffs_mgr->cache, g_spiffs_mgr->cache_sz, 0);
if (ret != SPIFFS_OK) {
if (ret == SPIFFS_ERR_NOT_A_FS) {
if (SPIFFS_format(g_spiffs_mgr->fs) == SPIFFS_OK) {
// second try to mount (already formatted)
ret = SPIFFS_mount(g_spiffs_mgr->fs, g_spiffs_mgr->cfg,
g_spiffs_mgr->work, g_spiffs_mgr->fds, g_spiffs_mgr->fds_sz,
g_spiffs_mgr->cache, g_spiffs_mgr->cache_sz, 0);
if (ret != SPIFFS_OK)
goto err;
} else
goto err;
} else
goto err;
}
return aos_register_fs(spiffs_mnt_path, &spiffs_ops, NULL);
err:
_spiffs_deinit();
return ret;
}
int vfs_spiffs_unregister(void)
{
SPIFFS_unmount(g_spiffs_mgr->fs);
_spiffs_deinit();
return aos_unregister_fs(spiffs_mnt_path);
}

View file

@ -0,0 +1,83 @@
This software component is used to help users port third-party programs, but WITHOUT ANY WARRANTY. The entire risk as to the quality and performance of the program is with you. Should the program prove defective, you assume the cost of all necessary servicing, repair or correction. The use of third-party programs must also follow its own permissive license.
how to use uffs under AliOS-Things
There are four steps.
1. get uffs zipball from official repo.
the repo of official repo is here.
https://github.com/rickyzheng/uffs
then you can download the zipball for master branch
https://codeload.github.com/rickyzheng/uffs/zip/master
decompress the uffs-master.zip, and copy the inc/ and uffs/ directories to aos/kernel/modules/fs/uffs
also you need copy the uffs_config.h to the inc/ directory.
(you can find the uffs_config.h in uffs-master.zip, you can choose the one under posix sub-directory, or you can define it by yourself).
2. add uffs source file to build system.
for GCC:
(1) declare uffs source file to the uffs.mk(aos/kerner/modules/fs/uffs/uffs.mk).
Example:
$(NAME)_SOURCES += uffs/uffs_badblock.c \
uffs/uffs_blockinfo.c \
uffs/uffs_buf.c \
uffs/uffs_crc.c \
uffs/uffs_debug.c \
uffs/uffs_device.c \
uffs/uffs_ecc.c \
uffs/uffs_fd.c \
uffs/uffs_find.c \
uffs/uffs_flash.c \
uffs/uffs_fs.c \
uffs/uffs_init.c \
uffs/uffs_mem.c \
uffs/uffs_mtb.c \
uffs/uffs_pool.c \
uffs/uffs_public.c \
uffs/uffs_tree.c \
uffs/uffs_utils.c \
uffs/uffs_version.c
(2) declare uffs include file to uffs.mk(aos/kerner/modules/fs/uffs/uffs.mk).
Example:
GLOBAL_INCLUDES += inc
(3) declare uffs dependences.
you can declare the dependence in your example's makefile ("example_name".mk) or platform's makefile ("platform_name".mk)
Example:
$(NAME)_COMPONENTS += modules.fs.uffs
for MDK or IAR:
(1) add uffs source files to the IDE project.
(2) add uffs include file to the IDE project.
(3) add uffs porting file to the IDE project.
file list:
uffs_aos.c
uffs_port.c
uffs_port.h
aos_uffs.h
3. add nand driver and compile
In order to use uffs, you should provide a nand driver which is needed by uffs.
you also should implement the NAND HAL interface based on your nand driver.
the HAL interface is declared in "aos/include/hal/soc/nand.h".
then you can use AliOS GCC build system or IDE like MDK or IAR to compile.
!!! Note !!!: for hal_nand_init interface, you should initialize the nand device
include config the page data size, spare size, block size, zone size and so on. (the detail parameters you can check the struct defination)
4. use uffs in your code
the uffs interface had already been attached to AliOS-Things vfs layer. vfs layer provide a lot of file operation functions,
you can use these functions to access the uffs. the function defination is located in "aos/include/aos/vfs.h".
Example:
*1. call vfs_uffs_register to mount the uffs. (MUST DO)
2. call aos_open("/uffs/uffs.txt", O_RDWR) to open a uffs.txt file.
3. call aos_close(fd) to close the file.
4. call vfs_uffs_unregister to unmount the uffs.
!!! None !!!: in AliOS-Things, the mount path for uffs self is "/", and the mount path for vfs layer is "/uffs". there are different!
For example:
if you call aos_open("/uffs/uffs.txt", O_RDWR), it's equal to call uffs_open("/uffs.txt", O_RDWR);
we suggest that you can use the aos_* function to access filesystem.

View file

@ -0,0 +1,20 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef FS_UFFS_H
#define FS_UFFS_H
#ifdef __cplusplus
extern "C" {
#endif
int vfs_uffs_register(void);
int vfs_uffs_unregister(void);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,37 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef UFFS_VFS_H
#define UFFS_VFS_H
#include "uffs_config.h"
#include "uffs/uffs_public.h"
#include <vfs_inode.h>
#include <vfs_register.h>
#ifndef CONFIG_UFFS_ECC_MODE
#define CONFIG_UFFS_ECC_MODE UFFS_ECC_NONE
#endif
#if CONFIG_UFFS_ECC_MODE == UFFS_ECC_NONE
#define CONFIG_UFFS_LAYOUT UFFS_LAYOUT_UFFS
#elif CONFIG_UFFS_ECC_MODE == UFFS_ECC_SOFT
#define CONFIG_UFFS_LAYOUT UFFS_LAYOUT_UFFS
#elif CONFIG_UFFS_ECC_MODE == UFFS_ECC_HW_AUTO
#define CONFIG_UFFS_LAYOUT UFFS_LAYOUT_FLASH
#endif
#ifndef CONFIG_UFFS_START_BLOCK
#define CONFIG_UFFS_START_BLOCK 0
#endif
#ifndef CONFIG_UFFS_END_BLOCK
#define CONFIG_UFFS_END_BLOCK 0xffffffff
#endif
#endif

View file

@ -0,0 +1,15 @@
NAME := uffs
$(NAME)_TYPE := kernel
$(NAME)_SOURCES += uffs_aos.c uffs_port.c
#default gcc
ifeq ($(COMPILER),)
$(NAME)_CFLAGS += -Wall -Werror -Wno-strict-aliasing -Wno-uninitialized
else ifeq ($(COMPILER),gcc)
$(NAME)_CFLAGS += -Wall -Werror -Wno-strict-aliasing -Wno-uninitialized
endif
GLOBAL_INCLUDES += include
GLOBAL_DEFINES += AOS_UFFS

View file

@ -0,0 +1,79 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "uffs_port.h"
#include "uffs/uffs_os.h"
#include <aos/aos.h>
#include <stdio.h>
#include <stdlib.h>
#define PFX "os : "
#define UFFS_TAG "uffs"
int uffs_SemCreate(OSSEM *sem)
{
return aos_mutex_new((aos_mutex_t *)sem);
}
int uffs_SemWait(OSSEM sem)
{
return aos_mutex_lock((aos_mutex_t *)(&sem), AOS_WAIT_FOREVER);
}
int uffs_SemSignal(OSSEM sem)
{
return aos_mutex_unlock((aos_mutex_t *)(&sem));
}
int uffs_SemDelete(OSSEM *sem)
{
aos_mutex_free((aos_mutex_t *)sem);
*sem = 0;
return 0;
}
int uffs_OSGetTaskId(void)
{
return 0;
}
unsigned int uffs_GetCurDateTime(void)
{
return 0;
}
#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0
static void * sys_malloc(struct uffs_DeviceSt *dev, unsigned int size)
{
uffs_Perror(UFFS_MSG_NORMAL, "system memory alloc %d bytes", size);
return aos_malloc(size);
}
static URET sys_free(struct uffs_DeviceSt *dev, void *p)
{
aos_free(p);
return U_SUCC;
}
void uffs_MemSetupSystemAllocator(uffs_MemAllocator *allocator)
{
allocator->malloc = sys_malloc;
allocator->free = sys_free;
}
#endif
static void output_dbg_msg(const char *msg);
static struct uffs_DebugMsgOutputSt m_dbg_ops = {
output_dbg_msg,
NULL,
};
static void output_dbg_msg(const char *msg)
{
LOGD(UFFS_TAG, "%s", msg);
}
void uffs_SetupDebugOutput(void)
{
uffs_InitDebugMessageOutput(&m_dbg_ops, UFFS_MSG_NOISY);
}

View file

@ -0,0 +1,666 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <string.h>
#include "uffs/uffs_fd.h"
#include "uffs/uffs_mtb.h"
#include "uffs/uffs_flash.h"
#include "uffs_port.h"
#include <hal/hal.h>
#define UFFS_NAME_LEN 256
static const char *uffs_mnt_path = "/uffs";
typedef struct {
nand_dev_t *dev;
struct uffs_StorageAttrSt *storage;
uffs_Device *udev;
uffs_MountTable *mtb;
} uffs_mgr_t;
static uffs_mgr_t *g_uffs_mgr = NULL;
typedef struct {
aos_dir_t dir;
uffs_DIR *d;
aos_dirent_t cur_dirent;
} uffs_dir_t;
static int nand_erase_block(uffs_Device *dev, uint32_t block)
{
nand_addr_t addr;
addr.zone = block / (((nand_dev_t *)(dev->_private))->config.zone_size);
addr.block = block - (addr.zone) * ((((nand_dev_t *)(dev->_private))->config.zone_size));
hal_nand_erase_block(dev->_private, &addr);
return 0;
}
static int nand_read_page(uffs_Device *dev, uint32_t block, uint32_t page, uint8_t *data,
int data_len, uint8_t *ecc,uint8_t *spare, int spare_len)
{
nand_addr_t addr;
int page_count, page_size, ret;
uint8_t *spare_buffer, *data_buffer = NULL;
addr.zone = block / (((nand_dev_t *)(dev->_private))->config.zone_size);
addr.block = block - (addr.zone) * ((((nand_dev_t *)(dev->_private))->config.zone_size));
addr.page = page;
page_size = ((nand_dev_t *)(dev->_private))->config.page_size;
page_count = data_len / page_size + ((data_len % page_size) > 0 ? 1 : 0);
if (data == NULL && spare == NULL) {
spare_buffer = (uint8_t *)aos_malloc(dev->attr->spare_size);
if (!spare_buffer) {
return -EIO;
}
memset(spare_buffer, 0, dev->attr->spare_size);
hal_nand_read_spare(dev->_private, &addr, spare_buffer, dev->attr->spare_size);
ret = *(spare_buffer + dev->attr->block_status_offs) == 0xFF ?
UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK;
aos_free(spare_buffer);
return ret;
}
if (data && data_len > 0) {
data_buffer = (uint8_t *)aos_malloc(page_size);
if (!data_buffer)
return -EIO;
memset(data_buffer, 0, page_size);
hal_nand_read_page(dev->_private, &addr, data_buffer, page_count);
memcpy(data, data_buffer, data_len);
aos_free(data_buffer);
}
if (spare && spare_len > 0)
hal_nand_read_spare(dev->_private, &addr, spare, spare_len);
return 0;
}
static int nand_write_page(uffs_Device *dev, uint32_t block, uint32_t page,
const uint8_t *data, int data_len, const uint8_t *spare, int spare_len)
{
nand_addr_t addr;
int page_count, page_size;
uint8_t *spare_buffer, *data_buffer = NULL;
addr.zone = block / (((nand_dev_t *)(dev->_private))->config.zone_size);
addr.block = block - (addr.zone) * ((((nand_dev_t *)(dev->_private))->config.zone_size));
addr.page = page;
page_size = ((nand_dev_t *)(dev->_private))->config.page_size;
page_count = data_len / page_size + ((data_len % page_size) > 0 ? 1 : 0);
if (data == NULL && spare == NULL) {
spare_buffer = (uint8_t *)aos_malloc(UFFS_MAX_SPARE_SIZE);
if (!spare_buffer)
return -EIO;
memset(spare_buffer, 0, UFFS_MAX_SPARE_SIZE);
*(spare_buffer + dev->attr->block_status_offs) = 0x00;
hal_nand_write_spare(dev->_private, &addr, spare_buffer, dev->attr->spare_size);
aos_free(spare_buffer);
}
if (data && data_len > 0) {
data_buffer = (uint8_t *)aos_malloc(page_size);
if (!data_buffer)
return -EIO;
memset(data_buffer, 0xff, page_size);
memcpy(data_buffer, data, data_len);
hal_nand_write_page(dev->_private, &addr, data_buffer, page_count);
aos_free(data_buffer);
}
if (spare && spare_len > 0) {
hal_nand_write_spare(dev->_private, &addr, (uint8_t *)spare, spare_len);
}
return 0;
}
static const uffs_FlashOps uffs_nand_ops =
{
.ReadPage = &nand_read_page,
.WritePage = &nand_write_page,
.EraseBlock = &nand_erase_block
};
static char* translate_relative_path(const char *path)
{
int len, prefix_len;
char *relpath, *p;
if (!path)
return NULL;
len = strlen(path);
prefix_len = strlen(uffs_mnt_path);
if (strncmp(uffs_mnt_path, path, prefix_len) != 0)
return NULL;
len = len - prefix_len;
relpath = (char *)aos_malloc(len + 1);
if (!relpath)
return NULL;
memset(relpath, 0, len + 1);
if (len > 0) {
p = (char *)(path + prefix_len);
memcpy(relpath, p, len);
}
relpath[len] = '\0';
return relpath;
}
static int _uffs_ret_to_err(int ret)
{
switch (ret) {
case UENOERR:
return 0;
case UEACCES:
return -EACCES;
case UEEXIST:
return -EEXIST;
case UEINVAL:
return -EINVAL;
case UEMFILE:
return -ENFILE;
case UENOENT:
return -ENOENT;
case UEBADF:
return -EBADF;
case UENOMEM:
return -ENOMEM;
case UEIOERR:
case UETIME:
return -EIO;
case UENOTDIR:
return -ENOTDIR;
case UEISDIR:
return -EISDIR;
case UEUNKNOWN_ERR:
default:
return -EIO;
}
}
static int _uffs_mode_conv(int flags)
{
int acc_mode, res = 0;
acc_mode = flags & O_ACCMODE;
if (acc_mode == O_RDONLY) {
res |= UO_RDONLY;
} else if (acc_mode == O_WRONLY) {
res |= UO_WRONLY;
} else if (acc_mode == O_RDWR) {
res |= UO_RDWR;
}
if ((flags & O_CREAT) && (flags & O_EXCL)) {
res |= UO_CREATE | UO_EXCL;
} else if ((flags & O_CREAT) && (flags & O_TRUNC)) {
res |= UO_CREATE | UO_TRUNC;
} else if (flags & O_APPEND) {
res |= UO_CREATE | UO_APPEND;
}
return res;
}
static int _uffs_open(file_t *fp, const char *path, int flags)
{
int fd;
char *relpath = NULL;
relpath = translate_relative_path(path);
if (!relpath)
return -EINVAL;
fd = uffs_open(relpath, _uffs_mode_conv(flags));
if (fd > 0) {
fp->f_arg = (void *)fd;
fd = 0;
} else {
fd = _uffs_ret_to_err(uffs_get_error());
}
aos_free(relpath);
return fd;
}
static int _uffs_close(file_t *fp)
{
int fd, ret;
fd = (int)(fp->f_arg);
ret = uffs_close(fd);
if (ret < 0) {
ret = _uffs_ret_to_err(uffs_get_error());
} else {
fp->f_arg = NULL;
}
return ret;
}
static ssize_t _uffs_read(file_t *fp, char *buf, size_t len)
{
ssize_t nbytes;
int fd;
fd = (int)(fp->f_arg);
nbytes = uffs_read(fd, buf, len);
if (nbytes < 0) {
nbytes = _uffs_ret_to_err(uffs_get_error());
}
return nbytes;
}
static ssize_t _uffs_write(file_t *fp, const char *buf, size_t len)
{
ssize_t nbytes;
int fd;
fd = (int)(fp->f_arg);
nbytes = uffs_write(fd, (void *)buf, len);
if (nbytes < 0) {
nbytes = _uffs_ret_to_err(uffs_get_error());
}
return nbytes;
}
static off_t _uffs_lseek(file_t *fp, off_t off, int whence)
{
off_t ret;
int fd;
fd = (int)(fp->f_arg);
ret = uffs_seek(fd, off, whence);
if (ret < 0) {
ret = _uffs_ret_to_err(uffs_get_error());
}
return ret;
}
static int _uffs_sync(file_t *fp)
{
int ret, fd;
fd = (int)(fp->f_arg);
ret = uffs_flush(fd);
if (ret < 0) {
ret = _uffs_ret_to_err(uffs_get_error());
} else {
ret = 0;
}
return ret;
}
static int _uffs_stat(file_t *fp, const char *path, struct stat *st)
{
int ret;
struct uffs_stat s;
char *relpath = NULL;
relpath = translate_relative_path(path);
if (!relpath)
return -EINVAL;
ret = uffs_stat(relpath, &s);
if (ret < 0) {
ret = _uffs_ret_to_err(uffs_get_error());
} else {
st->st_size = s.st_size;
st->st_mode = s.st_mode;
}
aos_free(relpath);
return ret;
}
static int _uffs_unlink(file_t *fp, const char *path)
{
int ret;
struct uffs_stat s;
char *relpath = NULL;
relpath = translate_relative_path(path);
if (!relpath)
return -EINVAL;
if (uffs_lstat(relpath, &s) < 0) {
aos_free(relpath);
return _uffs_ret_to_err(uffs_get_error());
}
switch(s.st_mode & US_IFMT) {
case US_IFREG:
ret = uffs_remove(relpath);
break;
case US_IFDIR:
ret = uffs_rmdir(relpath);
break;
default:
aos_free(relpath);
return -EIO;
}
if (ret < 0) {
ret = _uffs_ret_to_err(uffs_get_error());
}
aos_free(relpath);
return ret;
}
static int _uffs_rename(file_t *fp, const char *oldpath, const char *newpath)
{
int ret;
char *oldname = NULL;
char *newname = NULL;
oldname = translate_relative_path(oldpath);
if (!oldname)
return -EINVAL;
newname = translate_relative_path(newpath);
if (!newname) {
aos_free(oldname);
return -EINVAL;
}
ret = uffs_rename(oldname, newname);
if (ret < 0) {
ret = _uffs_ret_to_err(uffs_get_error());
}
aos_free(oldname);
aos_free(newname);
return ret;
}
static aos_dir_t* _uffs_opendir(file_t *fp, const char *path)
{
uffs_dir_t *dp = NULL;
char *relpath = NULL;
uffs_DIR *dir = NULL;
relpath = translate_relative_path(path);
if (!relpath)
return NULL;
dp = (uffs_dir_t *)aos_malloc(sizeof(uffs_dir_t) + UFFS_NAME_LEN);
if (!dp) {
aos_free(relpath);
return NULL;
}
memset(dp, 0, sizeof(uffs_dir_t) + UFFS_NAME_LEN);
dir = uffs_opendir(relpath);
if (!dir) {
aos_free(relpath);
aos_free(dp);
return NULL;
}
dp->d = dir;
aos_free(relpath);
return (aos_dir_t *)dp;
}
static aos_dirent_t* _uffs_readdir(file_t *fp, aos_dir_t *dir)
{
uffs_dir_t *dp;
struct uffs_dirent *e;
aos_dirent_t *out_dirent;
dp = (uffs_dir_t *)dir;
if (!dp)
return NULL;
e = uffs_readdir(dp->d);
if (!e) {
return NULL;
}
if (e->d_name[0] == 0)
return NULL;
dp->cur_dirent.d_ino = 0;
dp->cur_dirent.d_type = e->d_type;
strncpy(dp->cur_dirent.d_name, (char *)e->d_name, UFFS_NAME_LEN);
dp->cur_dirent.d_name[UFFS_NAME_LEN] = '\0';
out_dirent = &dp->cur_dirent;
return out_dirent;
}
static int _uffs_closedir(file_t *fp, aos_dir_t *dir)
{
int ret;
uffs_dir_t *dp = (uffs_dir_t *)dir;
if (!dp)
return -EINVAL;
ret = uffs_closedir(dp->d);
if (ret < 0) {
ret = _uffs_ret_to_err(uffs_get_error());
}
aos_free(dp);
return ret;
}
static int _uffs_mkdir(file_t *fp, const char *path)
{
int ret;
char *relpath = NULL;
relpath = translate_relative_path(path);
if (!relpath)
return -EINVAL;
ret = uffs_mkdir(relpath);
if (ret < 0) {
ret = _uffs_ret_to_err(uffs_get_error());
}
aos_free(relpath);
return ret;
}
static const fs_ops_t uffs_ops = {
.open = &_uffs_open,
.close = &_uffs_close,
.read = &_uffs_read,
.write = &_uffs_write,
.lseek = &_uffs_lseek,
.sync = &_uffs_sync,
.stat = &_uffs_stat,
.unlink = &_uffs_unlink,
.rename = &_uffs_rename,
.opendir = &_uffs_opendir,
.readdir = &_uffs_readdir,
.closedir = &_uffs_closedir,
.mkdir = &_uffs_mkdir,
.ioctl = NULL
};
static URET _uffs_device_init(uffs_Device *dev)
{
dev->attr->_private = NULL;
dev->ops = (struct uffs_FlashOpsSt *)&uffs_nand_ops;
return U_SUCC;
}
static URET _uffs_device_release(uffs_Device *dev)
{
return U_SUCC;
}
static int _uffs_fs_init(uffs_mgr_t *mgr)
{
int ret;
/* init low level nand device */
ret = hal_nand_init(mgr->dev);
if (ret != 0)
return ret;
/* init storage attribute struct */
mgr->storage->page_data_size = mgr->dev->config.page_size;
mgr->storage->pages_per_block = mgr->dev->config.block_size;
mgr->storage->spare_size = mgr->dev->config.spare_area_size;
mgr->storage->ecc_opt = CONFIG_UFFS_ECC_MODE;
mgr->storage->ecc_size = 0;
mgr->storage->block_status_offs = mgr->storage->ecc_size;
mgr->storage->layout_opt = CONFIG_UFFS_LAYOUT;
mgr->storage->total_blocks = mgr->dev->config.zone_number * mgr->dev->config.zone_size;
/* init uffs device struct */
mgr->udev->attr = mgr->storage;
mgr->udev->Init = _uffs_device_init;
mgr->udev->Release = _uffs_device_release;
mgr->udev->_private = mgr->dev;
#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0
uffs_MemSetupSystemAllocator(&mgr->udev->mem);
#endif
/* init uffs mount table */
mgr->mtb->mount = "/";
mgr->mtb->dev = mgr->udev;
mgr->mtb->start_block = (mgr->storage->total_blocks > CONFIG_UFFS_START_BLOCK) ?
CONFIG_UFFS_START_BLOCK : mgr->storage->total_blocks - 1;
mgr->mtb->end_block = (mgr->storage->total_blocks > CONFIG_UFFS_END_BLOCK) ?
CONFIG_UFFS_END_BLOCK : mgr->storage->total_blocks - 1;
return ret;
}
static void _uffs_deinit(void)
{
if (!g_uffs_mgr)
return;
if (g_uffs_mgr->dev) {
hal_nand_finalize(g_uffs_mgr->dev);
aos_free(g_uffs_mgr->dev);
}
if (g_uffs_mgr->storage) {
aos_free(g_uffs_mgr->storage);
}
if (g_uffs_mgr->udev) {
aos_free(g_uffs_mgr->udev);
}
if (g_uffs_mgr->mtb) {
aos_free(g_uffs_mgr->mtb);
}
aos_free(g_uffs_mgr);
g_uffs_mgr = NULL;
}
static int _uffs_init(void)
{
if (g_uffs_mgr)
return 0;
g_uffs_mgr = (uffs_mgr_t *)aos_malloc(sizeof(uffs_mgr_t));
if (!g_uffs_mgr)
return -ENOMEM;
memset(g_uffs_mgr, 0, sizeof(uffs_mgr_t));
/* nand flash device */
g_uffs_mgr->dev = (nand_dev_t *)aos_malloc(sizeof(nand_dev_t));
if (!g_uffs_mgr->dev)
goto err;
memset(g_uffs_mgr->dev, 0, sizeof(nand_dev_t));
/* uffs storage attribute struct */
g_uffs_mgr->storage = (struct uffs_StorageAttrSt *)aos_malloc(sizeof(struct uffs_StorageAttrSt));
if (!g_uffs_mgr->storage)
goto err;
memset(g_uffs_mgr->storage, 0, sizeof(struct uffs_StorageAttrSt));
/* uffs device */
g_uffs_mgr->udev = (uffs_Device *)aos_malloc(sizeof(uffs_Device));
if (!g_uffs_mgr->udev)
goto err;
memset(g_uffs_mgr->udev, 0, sizeof(uffs_Device));
/* uffs mount table */
g_uffs_mgr->mtb = (uffs_MountTable *)aos_malloc(sizeof(uffs_MountTable));
if (!g_uffs_mgr->mtb)
goto err;
memset(g_uffs_mgr->mtb, 0, sizeof(uffs_MountTable));
if (_uffs_fs_init(g_uffs_mgr) == 0)
return 0;
err:
_uffs_deinit();
return -1;
}
int vfs_uffs_register(void)
{
int ret = U_SUCC;
uffs_SetupDebugOutput();
ret = _uffs_init();
if (ret != U_SUCC) {
return ret;
}
ret = uffs_InitFileSystemObjects();
if (ret != U_SUCC) {
goto err;
}
ret = uffs_RegisterMountTable(g_uffs_mgr->mtb);
if (ret != U_SUCC) {
uffs_ReleaseFileSystemObjects();
goto err;
}
// first try to mount
ret = uffs_Mount(g_uffs_mgr->mtb->mount);
if (ret != U_SUCC) {
uffs_UnRegisterMountTable(g_uffs_mgr->mtb);
uffs_ReleaseFileSystemObjects();
goto err;
}
return aos_register_fs(uffs_mnt_path, &uffs_ops, NULL);
err:
_uffs_deinit();
return ret;
}
int vfs_uffs_unregister(void)
{
uffs_UnMount(g_uffs_mgr->mtb->mount);
uffs_UnRegisterMountTable(g_uffs_mgr->mtb);
uffs_ReleaseFileSystemObjects();
_uffs_deinit();
return aos_unregister_fs(uffs_mnt_path);
}

View file

@ -0,0 +1,4 @@
YAFFS2移植到AliOS-Things详细步骤见
https://yq.aliyun.com/articles/418865
此目录下yaffs_alios.c为AliOS-Things适配YAFFS2的操作系统相关接口yaffs_install_drv.c和yaffs_install_drv.h对接nand flash驱动的示例对接文件。

View file

@ -0,0 +1,8 @@
This software component is used to help users port third-party programs, but WITHOUT ANY WARRANTY. The entire risk as to the quality and performance of the program is with you. Should the program prove defective, you assume the cost of all necessary servicing, repair or correction. The use of third-party programs must also follow its own permissive license.
YAFFS2移植到AliOS-Things详细步骤见
https://yq.aliyun.com/articles/418865
此目录下yaffs_alios.c为AliOS-Things适配YAFFS2的操作系统相关接口yaffs_install_drv.c和yaffs_install_drv.h对接nand flash驱动的示例对接文件。
This directory include all the yaffs2 porting files.

View file

@ -0,0 +1,101 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "yaffs_osglue.h"
#include "k_api.h"
#define YAFFS_BG_TASK_STACKSIZE 1024
static kmutex_t yaffs_mutex;
static ktask_t yaffs_bg_task_obj;
cpu_stack_t yaffs_bg_task_buf[YAFFS_BG_TASK_STACKSIZE];
void yaffsfs_Lock(void)
{
krhino_mutex_lock(&yaffs_mutex, RHINO_WAIT_FOREVER);
}
void yaffsfs_Unlock(void)
{
krhino_mutex_unlock(&yaffs_mutex);
}
u32 yaffsfs_CurrentTime(void)
{
return krhino_sys_time_get();
}
static int yaffsfs_lastError;
int yaffsfs_GetLastError(void)
{
return yaffsfs_lastError;
}
void yaffsfs_SetError(int err)
{
yaffsfs_lastError = err;
}
void *yaffsfs_malloc(size_t size)
{
return krhino_mm_alloc(size);
}
void yaffsfs_free(void *ptr)
{
krhino_mm_free(ptr);
}
int yaffsfs_CheckMemRegion(const void *addr, size_t size, int write_request)
{
/* add code according to the hardware configuration */
return 0;
}
static void bg_gc_func(void *dummy)
{
struct yaffs_dev *dev;
int urgent = 0;
int result = 0;
int next_urgent = 0;
(void)dummy;
/* Sleep for a bit to allow start up */
krhino_task_sleep(2);
while (1) {
/* Iterate through devices, do bg gc updating ungency */
yaffs_dev_rewind();
next_urgent = 0;
while ((dev = yaffs_next_dev()) != NULL) {
result = yaffs_do_background_gc_reldev(dev, urgent);
if (result > 0)
next_urgent = 1;
}
urgent = next_urgent;
if (next_urgent) {
krhino_task_sleep(1);
} else {
krhino_task_sleep(5);
}
}
}
void yaffsfs_OSInitialisation(void)
{
krhino_mutex_create(&yaffs_mutex, "mutex");
krhino_task_create(&yaffs_bg_task_obj, "yaffs_bg_task", 0, 20,
50, yaffs_bg_task_buf, YAFFS_BG_TASK_STACKSIZE, bg_gc_func, 1);
}
void yaffs_bug_fn(const char *file_name, int line_no)
{
printf("yaffs bug detected %s:%d\n", file_name, line_no);
}

View file

@ -0,0 +1,99 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "yportenv.h"
#include "yaffs_guts.h"
#include "yaffs_install_drv.h"
static int nand_WriteChunk(struct yaffs_dev *dev, int nand_chunk,
const u8 *data, int data_len,
const u8 *oob, int oob_len)
{
/* add code according to your nand driver */
return YAFFS_OK;
}
static int nand_ReadChunk(struct yaffs_dev *dev, int nand_chunk,
u8 *data, int data_len,
u8 *oob, int oob_len,
enum yaffs_ecc_result *ecc_result)
{
/* add code according to your nand driver */
return YAFFS_OK;
}
static int nand_EraseBlock(struct yaffs_dev *dev, int block_no)
{
/* add code according to your nand driver */
return YAFFS_OK;
}
static int nand_MarkBad(struct yaffs_dev *dev, int block_no)
{
/* add code according to your nand driver */
return YAFFS_OK;
}
static int nand_CheckBad(struct yaffs_dev *dev, int block_no)
{
/* add code according to your nand driver */
return YAFFS_OK;
}
static int nand_Initialise(struct yaffs_dev *dev)
{
/* add code according to your nand driver */
return YAFFS_OK;
}
struct yaffs_dev *yaffs_install_drv(const char *name)
{
struct yaffs_dev *dev = NULL;
struct yaffs_param *param;
struct yaffs_driver *drv;
if(name == NULL) {
return NULL;
}
dev = malloc(sizeof(*dev));
if(dev == NULL)
{
return NULL;
}
memset(dev, 0, sizeof(*dev));
dev->param.name = name;
drv = &dev->drv;
drv->drv_write_chunk_fn = nand_WriteChunk;
drv->drv_read_chunk_fn = nand_ReadChunk;
drv->drv_erase_fn = nand_EraseBlock;
drv->drv_mark_bad_fn = nand_MarkBad;
drv->drv_check_bad_fn = nand_CheckBad;
drv->drv_initialise_fn = nand_Initialise;
param = &dev->param;
param->total_bytes_per_chunk = 2048;
param->chunks_per_block = 64;
param->start_block = 0;
param->end_block = 8192;
param->is_yaffs2 = 1;
param->use_nand_ecc=1;
param->n_reserved_blocks = 5;
param->wide_tnodes_disabled=0;
param->refresh_period = 1000;
param->n_caches = 10; // Use caches
param->enable_xattr = 1;
yaffs_add_device(dev);
return dev;
}

View file

@ -0,0 +1,13 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef __YAFFS_INSTALL_DRV_H__
#define __YAFFS_INSTALL_DRV_H__
struct yaffs_dev;
struct yaffs_dev *yflash2_install_drv(const char *name);
#endif

201
Living_SDK/LICENSE Normal file
View file

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.

19
Living_SDK/NOTICE Normal file
View file

@ -0,0 +1,19 @@
AliOS Things
Copyright 2017 Alibaba Group
This product includes software developed at Alibaba Group. (http://www.alibabagroup.com)
This product contains software sha256 developed
by Google Inc, licensed under the Copyright 2011 The Android Open Source Project.
This product contains software cJSON developed
by Dave Gamble, licensed under the Copyright (C) 2011 Gregory Nutt.
This product contains software md5 developed
by Cameron Rich, licensed under the Copyright (c) 2007, Cameron Rich.
This product contains software sha2 developed
by Aaron D. Gifford, licensed under the Copyright (c) 2000-2001, Aaron D. Gifford.
This product contains software mbedtls developed
by ARM Limited, licensed under the Copyright (C) 2006-2015.

53
Living_SDK/README.md Normal file
View file

@ -0,0 +1,53 @@
## 版本发布说明
飞燕SDK1.0.0 for AliOS Things
本次发布的是包含飞燕SDK 1.0.0版本的AliOS版本。
版本号 | 发布日期 | 下载链接 |
:-: | :-: | :-: |
1.0.0 | 20190715 | [下载](https://code.aliyun.com/living_platform/feiyan_sdk_for_alios/repository/archive.zip?ref=rel_1.0.0 "飞燕1.0.0版本") |
更新内容:
集成飞燕SDK 1.0.0版本
## 文档链接
[生活物联网平台(飞燕平台)官网](https://iot.aliyun.com/products/livinglink)
[飞燕平台文档中心](https://living.aliyun.com/doc#index.html)
[使用AliOS Things WiFi认证模组进行单品设备开发](https://living.aliyun.com/doc?#certificated_wifi.html)
[更多AliOS Things相关资料](https://github.com/alibaba/AliOS-Things/wiki)
## AliOS Things概述
AliOS Things 是 AliOS 家族旗下的、面向 IoT 领域的、轻量级物联网嵌入式操作系统。 AliOS Things 将致力于搭建云端一体化 IoT 基础设施,具备极致性能、极简开发、云端一体、丰富组件、安全防护等关键能力,并支持终端设备连接到阿里云 Link可广泛应用在智能家居、智慧城市、新出行等领域。
**极简开发**
- 基于Linux平台提供MCU虚拟化环境开发者直接在Linux平台上开发硬件无关的IoT应用和软件库使用GDB/Valgrind/SystemTap 等PC平台工具诊断开发问题
- 提供IDE支持系统/内核行为Trace、Mesh组网图形化显示
- 提供Shell交互支持内存踩踏、泄露、最大栈深度等各类侦测
- 提供面向组件的编译系统以及Cube工具支持灵活组合IoT产品软件栈
- 提供包括存储(掉电保护、负载均衡)在内的各类产品级别的组件
**即插即用的连接和丰富服务**
- 支持umesh即插即用网络技术设备上电自动连网
- 通过Alink与阿里云计算IoT服务无缝连接
**细颗粒度的FOTA更新**
- 支持应用代码独立编译映像IoT App独立极小映像升级
- 支持映像高度压缩
**彻底全面的安全保护**
- 提供系统和芯片级别安全保护
- 支持可信运行环境(支持ARMV8-M Trust Zone)
- 支持预置ID2根身份证和非对称密钥以及基于ID2的可信连接和服务
**高度优化的性能**
- 内核支持Idle Task成本Ram<1K,Rom<2k提供硬实时能力
- 提供YLOOP事件框架以及基于此整合的核心组件避免栈空间消耗核心架构良好支持极小FootPrint的设备
**解决IoT实际问题的特性演进**
- 更好的云端一体融合优化,更简单的开发体验,更安全,更优整体性能和算法支持,更多的特性演进,我们在路上

View file

@ -0,0 +1,31 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <k_api.h>
#include <aos/aos.h>
#ifdef WITH_LWIP
#include <aos/network.h>
#endif
#include "aos/uData.h"
#include <syscall_fnum.h>
/* ---------------------Macro--------------------- */
extern const int *syscall_ftbl;
#define SYSCALL_TBL syscall_ftbl
#define SYS_CALL0(nr, t) ((t (*)(void))(SYSCALL_TBL[nr]))()
#define SYS_CALL1(nr, t, t1, p1) ((t (*)(t1))(SYSCALL_TBL[nr]))(p1)
#define SYS_CALL2(nr, t, t1, p1, t2, p2) ((t (*)(t1, t2))(SYSCALL_TBL[nr]))(p1, p2)
#define SYS_CALL3(nr, t, t1, p1, t2, p2, t3, p3) ((t (*)(t1, t2, t3))(SYSCALL_TBL[nr]))(p1, p2, p3)
#define SYS_CALL4(nr, t, t1, p1, t2, p2, t3, p3, t4, p4) ((t (*)(t1, t2, t3, t4))(SYSCALL_TBL[nr]))(p1, p2, p3, p4)
#define SYS_CALL5(nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) ((t (*)(t1, t2, t3, t4, t5))(SYSCALL_TBL[nr]))(p1, p2, p3, p4, p5)
#define SYS_CALL6(nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) ((t (*)(t1, t2, t3, t4, t5, t6))(SYSCALL_TBL[nr]))(p1, p2, p3, p4, p5, p6)
#define SYS_CALL7(nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) ((t (*)(t1, t2, t3, t4, t5, t6, t7))(SYSCALL_TBL[nr]))(p1, p2, p3, p4, p5, p6, p7)
/* ---------------------Function--------------------- */
/* ---------------------syscall function--------------------- */

View file

@ -0,0 +1,505 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <syscall_uapi.h>
#include <k_api.h>
#include <aos/aos.h>
#include <hal/hal.h>
#ifdef CONFIG_AOS_MESH
#include <umesh.h>
#endif
#ifdef MBEDTLS_IN_KERNEL
#include <ali_crypto.h>
#endif
#define SYSCALL(nr, func)
#include <syscall_tbl.h>
#ifdef WITH_LWIP
#include <aos/network.h>
#endif
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/conn.h>
#include "ali_common.h"
#include "ali_core.h"
/* --------------------function-------------------- */
int __wrap_vprintf(char *format, va_list param)
{
return aos_vprintf(format, param);
}
int __wrap_fflush(FILE *stream)
{
return aos_fflush(stream);
}
/* --------------------function-------------------- */
/* --------------------k_task-------------------- */
ktask_t *krhino_cur_task_get(void)
{
return SYS_CALL0(SYS_KRHINO_CUR_TASK_GET, ktask_t *);
}
kstat_t krhino_task_info_set(ktask_t *task, size_t idx, void *info)
{
return SYS_CALL3(SYS_KRHINO_TASK_INFO_SET, kstat_t, ktask_t *, task,
size_t, idx, void *, info);
}
kstat_t krhino_task_info_get(ktask_t *task, size_t idx, void **info)
{
return SYS_CALL3(SYS_KRHINO_TASK_INFO_GET, kstat_t, ktask_t *, task,
size_t, idx, void **, info);
}
kstat_t krhino_task_sleep(tick_t dly)
{
return SYS_CALL1(SYS_KRHINO_TASK_SLEEP, kstat_t, tick_t, dly);
}
kstat_t krhino_task_dyn_create(ktask_t **task, const name_t *name, void *arg,
uint8_t pri, tick_t ticks, size_t stack,
task_entry_t entry, uint8_t autorun)
{
return SYS_CALL8(SYS_KRHINO_TASK_DYN_CREATE, kstat_t, ktask_t **, task, const name_t *, name,
void *, arg, uint8_t, pri, tick_t, ticks, size_t, stack,
task_entry_t, entry, uint8_t, autorun);
}
kstat_t krhino_task_dyn_del(ktask_t *task)
{
return SYS_CALL1(SYS_KRHINO_TASK_DYN_DEL, kstat_t, ktask_t *, task);
}
/* --------------------k_timer-------------------- */
sys_time_t krhino_sys_time_get(void)
{
return SYS_CALL0(SYS_KRHINO_SYS_TIME_GET, sys_time_t);
}
sys_time_t krhino_sys_tick_get(void)
{
return SYS_CALL0(SYS_KRHINO_SYS_TICK_GET, sys_time_t);
}
tick_t krhino_ms_to_ticks(sys_time_t ms)
{
return SYS_CALL1(SYS_KRHINO_MS_TO_TICKS, tick_t, sys_time_t, ms);
}
sys_time_t krhino_ticks_to_ms(tick_t ticks)
{
return SYS_CALL1(SYS_KRHINO_TICKS_TO_MS, sys_time_t, tick_t, ticks);
}
kstat_t krhino_timer_dyn_create(ktimer_t **timer, const name_t *name,
timer_cb_t cb,
sys_time_t first, sys_time_t round, void *arg, uint8_t auto_run)
{
return SYS_CALL7(SYS_KRHINO_TIMER_DYN_CREATE, kstat_t, ktimer_t **, timer, const name_t *, name,
timer_cb_t, cb, sys_time_t, first, sys_time_t, round, void *, arg,
uint8_t, auto_run);
}
kstat_t krhino_timer_dyn_del(ktimer_t *timer)
{
return SYS_CALL1(SYS_KRHINO_TIMER_DYN_DEL, kstat_t, ktimer_t *, timer);
}
kstat_t krhino_timer_start(ktimer_t *timer)
{
return SYS_CALL1(SYS_KRHINO_TIMER_START, kstat_t, ktimer_t *, timer);
}
kstat_t krhino_timer_stop(ktimer_t *timer)
{
return SYS_CALL1(SYS_KRHINO_TIMER_STOP, kstat_t, ktimer_t *, timer);
}
kstat_t krhino_timer_change(ktimer_t *timer, sys_time_t first, sys_time_t round)
{
return SYS_CALL3(SYS_KRHINO_TIMER_CHANGE, kstat_t, ktimer_t *, timer, sys_time_t, first, sys_time_t, round);
}
/* --------------------k_mutex-------------------- */
kstat_t krhino_mutex_create(kmutex_t *mutex, const name_t *name)
{
return SYS_CALL2(SYS_KRHINO_MUTEX_CREATE, kstat_t, kmutex_t *, mutex, const name_t *, name);
}
kstat_t krhino_mutex_del(kmutex_t *mutex)
{
return SYS_CALL1(SYS_KRHINO_MUTEX_DEL, kstat_t, kmutex_t *, mutex);
}
kstat_t krhino_mutex_lock(kmutex_t *mutex, tick_t ticks)
{
return SYS_CALL2(SYS_KRHINO_MUTEX_LOCK, kstat_t, kmutex_t *, mutex, tick_t, ticks);
}
kstat_t krhino_mutex_unlock(kmutex_t *mutex)
{
return SYS_CALL1(SYS_KRHINO_MUTEX_UNLOCK, kstat_t, kmutex_t *, mutex);
}
/* --------------------k_sem-------------------- */
kstat_t krhino_sem_create(ksem_t *sem, const name_t *name, sem_count_t count)
{
return SYS_CALL3(SYS_KRHINO_SEM_CREATE, kstat_t, ksem_t *, sem, const name_t *, name,
sem_count_t, count);
}
kstat_t krhino_sem_del(ksem_t *sem)
{
return SYS_CALL1(SYS_KRHINO_SEM_DEL, kstat_t, ksem_t *, sem);
}
kstat_t krhino_sem_take(ksem_t *sem, tick_t ticks)
{
return SYS_CALL2(SYS_KRHINO_SEM_TAKE, kstat_t, ksem_t *, sem, tick_t, ticks);
}
kstat_t krhino_sem_give(ksem_t *sem)
{
return SYS_CALL1(SYS_KRHINO_SEM_GIVE, kstat_t, ksem_t *, sem);
}
/* --------------------k_mm-------------------- */
void *krhino_mm_alloc(size_t size)
{
return SYS_CALL1(SYS_KRHINO_MM_ALLOC, void *, size_t, size);
}
void krhino_mm_free(void *ptr)
{
SYS_CALL1(SYS_KRHINO_MM_FREE, void, void *, ptr);
}
void *krhino_mm_realloc(void *oldmem, size_t newsize)
{
return SYS_CALL2(SYS_KRHINO_MM_REALLOC, void *, void *, oldmem, size_t, newsize);
}
/* ----------------k_buf_queue----------------- */
kstat_t krhino_buf_queue_send(kbuf_queue_t *queue, void *msg, size_t size)
{
return SYS_CALL3(SYS_KRHINO_BUF_QUEUE_SEND, kstat_t, kbuf_queue_t *, queue, void *, msg,
size_t, size);
}
kstat_t krhino_buf_queue_recv(kbuf_queue_t *queue, tick_t ticks, void *msg,
size_t *size)
{
return SYS_CALL4(SYS_KRHINO_BUF_QUEUE_RECV, kstat_t, kbuf_queue_t *, queue, tick_t, ticks,
void *, msg, size_t *, size);
}
kstat_t krhino_buf_queue_create(kbuf_queue_t *queue, const name_t *name,
void *buf, size_t size, size_t max_msg)
{
return SYS_CALL5(SYS_KRHINO_BUF_QUEUE_CREATE, kstat_t, kbuf_queue_t *, queue,
const name_t *, name, void *, buf, size_t, size, size_t, max_msg);
}
kstat_t krhino_buf_queue_del(kbuf_queue_t *queue)
{
return SYS_CALL1(SYS_KRHINO_BUF_QUEUE_DEL, kstat_t, kbuf_queue_t *, queue);
}
/* --------------------vfs-------------------- */
int aos_poll(struct pollfd *fds, int nfds, int timeout)
{
return SYS_CALL3(SYS_AOS_POLL, int, struct pollfd *, fds, int, nfds, int, timeout);
}
/* --------------------Framework-------------------- */
typedef void (*aos_event_cb)(input_event_t *event, void *private_data);
typedef void (*aos_call_t)(void *arg);
typedef void (*aos_poll_call_t)(int fd, void *arg);
int aos_register_event_filter(uint16_t type, aos_event_cb cb, void *priv)
{
return SYS_CALL3(SYS_REGISTER_EVENT_FILTER, int, uint16_t, type,
aos_event_cb, cb, void *, priv);
}
int aos_unregister_event_filter(uint16_t type, aos_event_cb cb, void *priv)
{
return SYS_CALL3(SYS_UNREGISTER_EVENT_FILTER, int, uint16_t, type,
aos_event_cb, cb, void *, priv);
}
int aos_post_event(uint16_t type, uint16_t code, unsigned long value)
{
return SYS_CALL3(SYS_POST_EVENT, int, uint16_t, type, uint16_t, code,
unsigned long, value);
}
int aos_poll_read_fd(int fd, aos_poll_call_t action, void *param)
{
return SYS_CALL3(SYS_POLL_READ_FD, int, int, fd, aos_poll_call_t, action,
void *, param);
}
void aos_cancel_poll_read_fd(int fd, aos_poll_call_t action, void *param)
{
return SYS_CALL3(SYS_CANCEL_POLL_READ_FD, void, int, fd,
aos_poll_call_t, action, void *, param);
}
int aos_post_delayed_action(int ms, aos_call_t action, void *arg)
{
return SYS_CALL3(SYS_POST_DELAYED_ACTION, int, int, ms, aos_call_t, action,
void *, arg);
}
void aos_cancel_delayed_action(int ms, aos_call_t action, void *arg)
{
return SYS_CALL3(SYS_CANCEL_DELAYED_ACTION, void, int, ms,
aos_call_t, action, void *, arg);
}
int aos_schedule_call(aos_call_t action, void *arg)
{
return SYS_CALL2(SYS_SCHEDULE_CALL, int, aos_call_t, action, void *, arg);
}
typedef void *aos_loop_t;
aos_loop_t aos_loop_init(void)
{
return SYS_CALL0(SYS_LOOP_INIT, aos_loop_t);
}
aos_loop_t aos_current_loop(void)
{
return SYS_CALL0(SYS_CURRENT_LOOP, aos_loop_t);
}
void aos_loop_run(void)
{
return SYS_CALL0(SYS_LOOP_RUN, void);
}
void aos_loop_exit(void)
{
return SYS_CALL0(SYS_LOOP_EXIT, void);
}
void aos_loop_destroy(void)
{
return SYS_CALL0(SYS_LOOP_DESTROY, void);
}
int aos_loop_schedule_call(aos_loop_t *loop, aos_call_t action, void *arg)
{
return SYS_CALL3(SYS_LOOP_SCHEDULE_CALL, int, aos_loop_t *, loop,
aos_call_t, action, void *, arg);
}
void *aos_loop_schedule_work(int ms, aos_call_t action, void *arg1,
aos_call_t fini_cb, void *arg2)
{
return SYS_CALL5(SYS_LOOP_SCHEDULE_WORK, void *, int, ms,
aos_call_t, action, void *, arg1, aos_call_t, fini_cb,
void *, arg2);
}
void aos_cancel_work(void *work, aos_call_t action, void *arg1)
{
return SYS_CALL3(SYS_CANCEL_WORK, void, void *, work, aos_call_t, action,
void *, arg1);
}
/* --------------------OTA-------------------- */
int ais_ota_bt_storage_init(void)
{
return SYS_CALL0(SYS_AIS_OTA_BT_STORAGE_INIT, int);
}
int ais_ota_get_local_addr(bt_addr_le_t *addr)
{
return SYS_CALL1(SYS_AIS_OTA_GET_LOCAL_ADDR, int, bt_addr_le_t *, addr);
}
/* --------------------ALINK-------------------- */
int alink_start(struct device_config *dev_conf)
{
SYS_CALL1(SYS_ALINK_START, int, struct device_config *, dev_conf);
}
int alink_end(void)
{
SYS_CALL0(SYS_ALINK_END, int);
}
void alink_post(uint8_t *buffer, uint32_t length)
{
SYS_CALL2(SYS_ALINK_POST, void, uint8_t *, buffer, uint32_t, length);
}
void alink_post_fast(uint8_t *buffer, uint32_t length)
{
SYS_CALL2(SYS_ALINK_POST_FAST, void, uint8_t *, buffer, uint32_t, length);
}
/* --------------------BLE-------------------- */
void hrs_init(u8_t blsc)
{
SYS_CALL1(SYS_HRS_INIT, void, u8_t, blsc);
}
void hrs_notify(void)
{
SYS_CALL0(SYS_HRS_NOTIFY, void);
}
void bas_init(void)
{
SYS_CALL0(SYS_BAS_INIT, void);
}
void bas_notify(void)
{
SYS_CALL0(SYS_BAS_NOTIFY, void);
}
void dis_init(const char *model, const char *manuf)
{
SYS_CALL2(SYS_DIS_INIT, void, const char *, model, const char *, manuf);
}
int bt_le_adv_start(const struct bt_le_adv_param *param,
const struct bt_data *ad, size_t ad_len,
const struct bt_data *sd, size_t sd_len)
{
return SYS_CALL5(SYS_BT_LE_ADV_START, int, const struct bt_le_adv_param *, param,
const struct bt_data *, ad, size_t, ad_len,
const struct bt_data *, sd, size_t, sd_len);
}
const bt_addr_le_t *bt_conn_get_dst(const struct bt_conn *conn)
{
return SYS_CALL1(SYS_BT_CONN_GET_DST, const bt_addr_le_t *, const struct bt_conn *, conn);
}
struct bt_conn *bt_conn_ref(struct bt_conn *conn)
{
return SYS_CALL1(SYS_BT_CONN_REF, struct bt_conn *, struct bt_conn *, conn);
}
int bt_conn_security(struct bt_conn *conn, bt_security_t sec)
{
return SYS_CALL2(SYS_BT_CONN_SECURITY, int, struct bt_conn *, conn, bt_security_t, sec);
}
int hci_driver_init(void)
{
return SYS_CALL0(SYS_HCI_DRIVER_INIT, int);
}
int bt_enable(bt_ready_cb_t cb)
{
return SYS_CALL1(SYS_BT_ENABLE, int, bt_ready_cb_t, cb);
}
int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb)
{
return SYS_CALL1(SYS_BT_CONN_AUTH_CB_REGISTER, int, const struct bt_conn_auth_cb *, cb);
}
void bt_conn_cb_register(struct bt_conn_cb *cb)
{
SYS_CALL1(SYS_BT_CONN_CB_REGISTER, void, struct bt_conn_cb *, cb);
}
void bt_conn_unref(struct bt_conn *conn)
{
SYS_CALL1(SYS_BT_CONN_UNREF, void, struct bt_conn *, conn);
}
void ali_reset(void * p_ali)
{
SYS_CALL1(SYS_BT_ALI_RESET, void, void *, p_ali);
}
ret_code_t ali_init(void * p_ali, ali_init_t const * p_init)
{
return SYS_CALL2(SYS_BT_ALI_INIT, ret_code_t, void *, p_ali, ali_init_t const *, p_init);
}
ret_code_t ali_send_indicate(void * p_ali, uint8_t * p_data, uint16_t length)
{
return SYS_CALL3(SYS_BT_ALI_SEND_INDICATE, ret_code_t, void *, p_ali, uint8_t *, p_data, uint16_t, length);
}
ret_code_t ali_send_notify(void * p_ali, uint8_t * p_data, uint16_t length)
{
return SYS_CALL3(SYS_BT_ALI_SEND_NOTIFY, ret_code_t, void *, p_ali, uint8_t *, p_data, uint16_t, length);
}
ret_code_t ali_get_manuf_spec_adv_data(void * p_ali, uint8_t * p_data, uint16_t * length)
{
return SYS_CALL3(SYS_BT_ALI_GET_MANUF_SPEC_ADV_DATA, ret_code_t, void *, p_ali, uint8_t *, p_data, uint16_t, length);
}
uint32_t *fetch_ali_context()
{
return SYS_CALL0(SYS_BT_FETCH_ALI_CONTEXT, uint32_t *);
}
/* -----------------end BLE-------------------- */
/* -----------------OTHERS--------------------- */
int get_errno(void)
{
return SYS_CALL0(SYS_GET_ERRNO, int);
}
void set_errno(int err)
{
return SYS_CALL1(SYS_SET_ERRNO, void, int, err);
}
int32_t hal_uart_send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout)
{
return SYS_CALL4(SYS_HAL_UART_SEND, int32_t, uart_dev_t *, uart, const void *, data,
uint32_t, size, uint32_t, timeout);
}
int aos_vprintf(char *format, va_list param)
{
return SYS_CALL2(SYS_VPRINTF, int, char *, format, va_list, param);
}
int aos_fflush(FILE *stream)
{
return SYS_CALL1(SYS_FFLUSH, int, FILE *, stream);
}
/* -----------------end OTHERS-------------------- */

View file

@ -0,0 +1,22 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef YOS_SYSCALL_UAPI_H
#define YOS_SYSCALL_UAPI_H
extern const int *syscall_tbl;
#define SYSCALL_TBL syscall_tbl
#define SYS_CALL0(nr, t) ((t (*)(void))(SYSCALL_TBL[nr]))()
#define SYS_CALL1(nr, t, t1, p1) ((t (*)(t1))(SYSCALL_TBL[nr]))(p1)
#define SYS_CALL2(nr, t, t1, p1, t2, p2) ((t (*)(t1, t2))(SYSCALL_TBL[nr]))(p1, p2)
#define SYS_CALL3(nr, t, t1, p1, t2, p2, t3, p3) ((t (*)(t1, t2, t3))(SYSCALL_TBL[nr]))(p1, p2, p3)
#define SYS_CALL4(nr, t, t1, p1, t2, p2, t3, p3, t4, p4) ((t (*)(t1, t2, t3, t4))(SYSCALL_TBL[nr]))(p1, p2, p3, p4)
#define SYS_CALL5(nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) ((t (*)(t1, t2, t3, t4, t5))(SYSCALL_TBL[nr]))(p1, p2, p3, p4, p5)
#define SYS_CALL6(nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) ((t (*)(t1, t2, t3, t4, t5, t6))(SYSCALL_TBL[nr]))(p1, p2, p3, p4, p5, p6)
#define SYS_CALL7(nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) ((t (*)(t1, t2, t3, t4, t5, t6, t7))(SYSCALL_TBL[nr]))(p1, p2, p3, p4, p5, p6, p7)
#define SYS_CALL8(nr, t, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8) ((t (*)(t1, t2, t3, t4, t5, t6, t7, t8))(SYSCALL_TBL[nr]))(p1, p2, p3, p4, p5, p6, p7, p8)
#endif

View file

@ -0,0 +1,14 @@
NAME := umbins
$(NAME)_MBINS_TYPE := app
$(NAME)_INCLUDES := ./ \
../../../kernel/ksyscall/kmbins
$(NAME)_CFLAGS += -Wall -Werror
$(NAME)_COMPONENTS :=
$(NAME)_SOURCES := syscall_uapi.c
GLOBAL_DEFINES += AOS_BINS

View file

@ -0,0 +1,34 @@
NAME := board_amebaz_dev
JTAG := jlink_swd
$(NAME)_TYPE := kernel
MODULE := AmebaZ
HOST_ARCH := Cortex-M4
HOST_MCU_FAMILY := rtl8710bn
SUPPORT_BINS := no
$(NAME)_SOURCES := board.c
GLOBAL_INCLUDES += .
GLOBAL_DEFINES += STDIO_UART=0
CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_AMEBAZ
CONFIG_SYSINFO_DEVICE_NAME := AMEBAZ
CONFIG_BOARD_NAME = AMEBAZ
$(info CONFIG_BOARD_NAME : $(CONFIG_BOARD_NAME))
GLOBAL_DEFINES += BOARD_NAME=AMEBAZ
GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\"
GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\"
#GLOBAL_CFLAGS += -DSYSINFO_KERNEL_VERSION=\"$(CONFIG_SYSINFO_KERNEL_VERSION)\"
#GLOBAL_CFLAGS += -DSYSINFO_APP_VERSION=\"$(CONFIG_SYSINFO_APP_VERSION)\"
#include $(SOURCE_ROOT)/board/rtl8710bn/export-rom_symbol_v01.txt
#GLOBAL_CFLAGS += -L $(SOURCE_ROOT)/board/amebaz_dev
# Extra build target in mico_standard_targets.mk, include bootloader, and copy output file to eclipse debug file (copy_output_for_eclipse)
EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/download.mk
EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_crc_bin.mk

View file

@ -0,0 +1,77 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "hal/soc/soc.h"
#include <aos/kernel.h>
#include <aos/aos.h>
/* Logic partition on flash devices */
const hal_logic_partition_t hal_partitions[] =
{
[HAL_PARTITION_BOOTLOADER] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "Bootloader",
.partition_start_addr = 0x0,
.partition_length = 0x8000, //32k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
},
[HAL_PARTITION_APPLICATION] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "Application",
.partition_start_addr = 0xB000,
.partition_length = 0xF2000, //568k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_1] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER1",
.partition_start_addr = 0xFD000,
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_2] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER2",
.partition_start_addr = 0xFE000,
.partition_length = 0x2000, // 8k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_OTA_TEMP] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "OTA Storage",
.partition_start_addr = 0x100000,
.partition_length = 0xF2000, //568k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_3] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER3",
.partition_start_addr = 0x1FD000,
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_4] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER4",
.partition_start_addr = 0x1FE000,
.partition_length = 0x2000,// 8k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
};
void board_init(void)
{
}

View file

@ -0,0 +1,166 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#define HARDWARE_REVISION "V1.0"
#define MODEL "AmebaZ"
#ifdef BOOTLOADER
#define STDIO_UART 0
#define STDIO_UART_BUADRATE 921600
#else
#define STDIO_UART 0
#define STDIO_UART_BUADRATE 921600
#endif
/******************************************************
* Macros
******************************************************/
/******************************************************
* Constants
******************************************************/
/******************************************************
* Enumerations
******************************************************/
#define MICO_UNUSED 0xFF
typedef enum
{
MICO_SYS_LED,
MICO_RF_LED,
BOOT_SEL,
MFG_SEL,
EasyLink_BUTTON,
MICO_GPIO_1 ,
MICO_GPIO_2,
//MICO_GPIO_3,
MICO_GPIO_4,
MICO_GPIO_5,
MICO_GPIO_6,
MICO_GPIO_7,
MICO_GPIO_8,
MICO_GPIO_9,
MICO_GPIO_10,
//MICO_GPIO_11,
MICO_GPIO_12,
MICO_GPIO_13,
MICO_GPIO_14,
//MICO_GPIO_15,
//MICO_GPIO_16,
//MICO_GPIO_17,
MICO_GPIO_18,
MICO_GPIO_19,
MICO_GPIO_20,
MICO_GPIO_21,
MICO_GPIO_22,
MICO_GPIO_23,
//MICO_GPIO_24,
//MICO_GPIO_25,
//MICO_GPIO_26,
//MICO_GPIO_27,
//MICO_GPIO_28,
MICO_GPIO_29,
//MICO_GPIO_30,
MICO_GPIO_MAX, /* Denotes the total number of GPIO port aliases. Not a valid GPIO alias */
MICO_GPIO_NONE,
} mico_gpio_t;
typedef enum
{
MICO_SPI_1,
MICO_SPI_2,
MICO_SPI_3,
MICO_SPI_MAX, /* Denotes the total number of SPI port aliases. Not a valid SPI alias */
MICO_SPI_NONE,
} mico_spi_t;
typedef enum
{
MICO_I2C_1,
MICO_I2C_2,
MICO_I2C_MAX, /* Denotes the total number of I2C port aliases. Not a valid I2C alias */
MICO_I2C_NONE,
} mico_i2c_t;
typedef enum
{
MICO_PWM_1,
MICO_PWM_2,
MICO_PWM_3,
MICO_PWM_4,
MICO_PWM_MAX, /* Denotes the total number of PWM port aliases. Not a valid PWM alias */
MICO_PWM_NONE,
} mico_pwm_t;
typedef enum
{
MICO_ADC_1,
MICO_ADC_2,
MICO_ADC_3,
MICO_ADC_MAX, /* Denotes the total number of ADC port aliases. Not a valid ADC alias */
MICO_ADC_NONE,
} mico_adc_t;
typedef enum
{
MICO_UART_1,
MICO_UART_2,
MICO_UART_MAX, /* Denotes the total number of UART port aliases. Not a valid UART alias */
MICO_UART_NONE,
} mico_uart_t;
typedef enum
{
MICO_FLASH_EMBEDDED,
MICO_FLASH_SPI,
MICO_FLASH_MAX,
MICO_FLASH_NONE,
} mico_flash_t;
typedef enum
{
MICO_PARTITION_USER_MAX
} mico_user_partition_t;
#ifdef BOOTLOADER
#define STDIO_UART MICO_UART_NONE
#define STDIO_UART_BAUDRATE (115200)
#else
#define STDIO_UART MICO_UART_NONE
#define STDIO_UART_BAUDRATE (115200)
#endif
#define UART_FOR_APP MICO_UART_1
#define MFG_TEST MICO_UART_1
#define CLI_UART MICO_UART_1
/* Components connected to external I/Os*/
#define Standby_SEL (MICO_GPIO_29)
/* I/O connection <-> Peripheral Connections */
#define MICO_I2C_CP (MICO_I2C_1)
//#define USE_MICO_SPI_FLASH
#define MICO_FLASH_FOR_PARA MICO_FLASH_SPI
#define PARA_START_ADDRESS (uint32_t)0x00000020
#define PARA_END_ADDRESS (uint32_t)0x00003FFF
#define PARA_FLASH_SIZE (PARA_END_ADDRESS - PARA_START_ADDRESS + 1) /* 4k bytes*/
#ifdef __cplusplus
} /*extern "C" */
#endif

View file

@ -0,0 +1,225 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef CONFIG_H
#define CONFIG_H
/* chip level conf */
#ifndef RHINO_CONFIG_LITTLE_ENDIAN
#define RHINO_CONFIG_LITTLE_ENDIAN 1
#endif
#ifndef RHINO_CONFIG_CPU_STACK_DOWN
#define RHINO_CONFIG_CPU_STACK_DOWN 1
#endif
/* kernel feature conf */
#ifndef RHINO_CONFIG_SEM
#define RHINO_CONFIG_SEM 1
#endif
#ifndef RHINO_CONFIG_QUEUE
#define RHINO_CONFIG_QUEUE 1
#endif
#ifndef RHINO_CONFIG_TASK_SEM
#define RHINO_CONFIG_TASK_SEM 1
#endif
#ifndef RHINO_CONFIG_EVENT_FLAG
#define RHINO_CONFIG_EVENT_FLAG 1
#endif
#ifndef RHINO_CONFIG_TIMER
#define RHINO_CONFIG_TIMER 1
#endif
#ifndef RHINO_CONFIG_BUF_QUEUE
#define RHINO_CONFIG_BUF_QUEUE 1
#endif
#ifndef RHINO_CONFIG_MM_BLK
#define RHINO_CONFIG_MM_BLK 1
#endif
#ifndef RHINO_CONFIG_MM_DEBUG
#define RHINO_CONFIG_MM_DEBUG 1
#endif
#ifndef RHINO_CONFIG_MM_TLF
#define RHINO_CONFIG_MM_TLF 1
#endif
#ifndef RHINO_CONFIG_MM_TLF_BLK_SIZE
#define RHINO_CONFIG_MM_TLF_BLK_SIZE 8192
#endif
#define K_MM_STATISTIC 1
#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT
#define RHINO_CONFIG_MM_MAXMSIZEBIT 19
#endif
#ifndef RHINO_CONFIG_GCC_RETADDR
#define RHINO_CONFIG_GCC_RETADDR 1
#endif
#ifndef RHINO_CONFIG_MM_LEAKCHECK
#define RHINO_CONFIG_MM_LEAKCHECK 1
#endif
#ifndef RHINO_CONFIG_RINGBUF_VENDOR
#define RHINO_CONFIG_RINGBUF_VENDOR 0
#endif
#ifndef RHINO_CONFIG_KOBJ_SET
#define RHINO_CONFIG_KOBJ_SET 1
#endif
/* kernel task conf */
#ifndef RHINO_CONFIG_TASK_SUSPEND
#define RHINO_CONFIG_TASK_SUSPEND 1
#endif
#ifndef RHINO_CONFIG_TASK_INFO
#define RHINO_CONFIG_TASK_INFO 1
#endif
#ifndef RHINO_CONFIG_TASK_DEL
#define RHINO_CONFIG_TASK_DEL 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK
#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 1
#endif
#ifndef RHINO_CONFIG_TASK_WAIT_ABORT
#define RHINO_CONFIG_TASK_WAIT_ABORT 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK
#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1
#endif
#ifndef RHINO_CONFIG_SCHED_RR
#define RHINO_CONFIG_SCHED_RR 1
#endif
#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT
#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50
#endif
#ifndef RHINO_CONFIG_PRI_MAX
#define RHINO_CONFIG_PRI_MAX 62
#endif
#ifndef RHINO_CONFIG_USER_PRI_MAX
#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2)
#endif
/* kernel workqueue conf */
#ifndef RHINO_CONFIG_WORKQUEUE
#define RHINO_CONFIG_WORKQUEUE 1
#endif
#ifndef RHINO_CONFIG_WORKQUEUE_STACK_SIZE
#define RHINO_CONFIG_WORKQUEUE_STACK_SIZE 768
#endif
/* kernel mm_region conf */
#ifndef RHINO_CONFIG_MM_REGION_MUTEX
#define RHINO_CONFIG_MM_REGION_MUTEX 0
#endif
/* kernel timer&tick conf */
#ifndef RHINO_CONFIG_HW_COUNT
#define RHINO_CONFIG_HW_COUNT 0
#endif
#ifndef RHINO_CONFIG_TICK_TASK
#define RHINO_CONFIG_TICK_TASK 0
#endif
#if (RHINO_CONFIG_TICK_TASK > 0)
#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE
#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256
#endif
#ifndef RHINO_CONFIG_TICK_TASK_PRI
#define RHINO_CONFIG_TICK_TASK_PRI 1
#endif
#endif
#ifndef RHINO_CONFIG_TICKLESS
#define RHINO_CONFIG_TICKLESS 0
#endif
#ifndef RHINO_CONFIG_TICKS_PER_SECOND
#define RHINO_CONFIG_TICKS_PER_SECOND 1000
#endif
/* must be 2^n size!, such as 1, 2, 4, 8, 16,32, etc....... */
#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY
#define RHINO_CONFIG_TICK_HEAD_ARRAY 8
#endif
/*must reserve enough stack size for timer cb will consume*/
#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE
#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 300
#endif
#ifndef RHINO_CONFIG_TIMER_RATE
#define RHINO_CONFIG_TIMER_RATE 1
#endif
#ifndef RHINO_CONFIG_TIMER_TASK_PRI
#define RHINO_CONFIG_TIMER_TASK_PRI 5
#endif
/* kernel intrpt conf */
#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET
#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0
#endif
#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK
#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0
#endif
#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL
#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u
#endif
#ifndef RHINO_CONFIG_INTRPT_GUARD
#define RHINO_CONFIG_INTRPT_GUARD 0
#endif
/* kernel dyn alloc conf */
#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC
#define RHINO_CONFIG_KOBJ_DYN_ALLOC 1
#endif
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG
#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30
#endif
#ifndef RHINO_CONFIG_K_DYN_TASK_STACK
#define RHINO_CONFIG_K_DYN_TASK_STACK 256
#endif
#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI
#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 6
#endif
#endif
/* kernel idle conf */
#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE
#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200
#endif
/* kernel hook conf */
#ifndef RHINO_CONFIG_USER_HOOK
#define RHINO_CONFIG_USER_HOOK 0
#endif
/* kernel stats conf */
#ifndef RHINO_CONFIG_SYSTEM_STATS
#define RHINO_CONFIG_SYSTEM_STATS 1
#endif
#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS
#define RHINO_CONFIG_DISABLE_SCHED_STATS 0
#endif
#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS
#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_STATS
#define RHINO_CONFIG_CPU_USAGE_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI
#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2)
#endif
#ifndef RHINO_CONFIG_TASK_SCHED_STATS
#define RHINO_CONFIG_TASK_SCHED_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK
#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256
#endif
#ifndef RHINO_CONFIG_CPU_NUM
#define RHINO_CONFIG_CPU_NUM 1
#endif
/* kernel trace conf */
#ifndef RHINO_CONFIG_TRACE
#define RHINO_CONFIG_TRACE 0
#endif
#endif /* CONFIG_H */

Binary file not shown.

View file

@ -0,0 +1,47 @@
config AOS_BOARD_ASR5501
bool "ASR5501"
select AOS_MCU_ASR5501
select AOS_COMP_KERNEL_INIT
select AOS_COMP_LWIP if AOS_NETWORK_SAL
select AOS_COMP_NETMGR
help
if AOS_BOARD_ASR5501
# Configurations for board asr5501
config DEBUG_CONFIG_PANIC
bool "Enable debug panic feature"
default y
help
set to y if you want to enable panic debug feature when system crash happened,
default y
config DEBUG_CONFIG_BACKTRACE
bool "Enable stack backtrace feature"
default y
help
set to y if you want to enable stack backtrace feature when system crash happened,
default y
# "BSP SUPPORT FEATURE"
config BSP_SUPPORT_UART
bool
default y
config BSP_SUPPORT_GPIO
bool
default y
config BSP_SUPPORT_FLASH
bool
default y
config BSP_SUPPORT_I2C
bool
default y
config BSP_SUPPORT_WIFI
bool
default y
endif

View file

@ -0,0 +1,43 @@
## Overview
This is a board demo for consulting, not a true realization.
## Feature of Board
## Directories
```sh
aaboard_demo # configuration files for board aaboard_demo
=============================================================================================================
Dir\File Description Necessary for kernel run
=============================================================================================================
|-- drivers # board peripheral driver N
|-- config
| |-- board.h # board config file, define for user, such as uart port num Y
| |-- k_config.c # user's kernel hook and mm memory region define Y
| |-- k_config.h # kernel config file .h Y
| |-- partition_conf.c # board flash config file N
|-- startup
| |-- board.c # board_init implement Y
| |-- startup.c # main entry file Y
| |-- startup_gcc.s # board startup assember for gcc Y
| |-- startup_iar.s # board startup assember for iar Y
| |-- startup_keil.s # board startup assember for keil Y
|-- aaboard_demo.icf # linkscript file for iar Y
|-- aaboard_demo.ld # linkscript file for gcc Y
|-- aaboard_demo.sct # linkscript file for sct Y
|-- aos.mk # board makefile Y
|-- Config.in # menuconfig component config Y
|-- ucube.py # config for CI autorun app N
```
## Board Hardware Resources
## Pin Mapping
## Driver Support
## Programming
## Debugging
## Update log
## Reference

View file

@ -0,0 +1,50 @@
NAME := board_asr5501
MODULE := ASR5501
HOST_ARCH := Cortex-M4
HOST_MCU_FAMILY := asr5501
SUPPORT_BINS := no
define get-os-version
"AOS-R"-$(CURRENT_TIME)
endef
CONFIG_SYSINFO_OS_VERSION := $(call get-os-version)
$(NAME)_SOURCES := config/partition_conf.c \
config/k_config.c \
startup/startup.c \
startup/startup_cm4.S \
startup/board.c
GLOBAL_INCLUDES += . \
./config \
./drivers/include \
./drivers/include/lwip_if \
$(NAME)_CFLAGS += -DLEGA_CM4 -DALIOS_SUPPORT -DWIFI_DEVICE -D_SPI_FLASH_ENABLE_ -DDCDC_PFMMODE_CLOSE -DCFG_MIMO_UF
$(NAME)_CFLAGS += -DCFG_BATX=1 -DCFG_BARX=1 -DCFG_REORD_BUF=4 -DCFG_SPC=4 -DCFG_TXDESC0=4 -DCFG_TXDESC1=4 -DCFG_TXDESC2=4 -DCFG_TXDESC3=4 -DCFG_TXDESC4=4 -DCFG_CMON -DCFG_MDM_VER_V21 -DCFG_SOFTAP_SUPPORT -DCFG_SNIFFER_SUPPORT -DCFG_DBG=2 -D__FPU_PRESENT=1 -DDX_CC_TEE -DHASH_SHA_512_SUPPORTED -DCC_HW_VERSION=0xF0 -DDLLI_MAX_BUFF_SIZE=0x10000 -DSSI_CONFIG_TRNG_MODE=0
#default a0v2 config
ifeq ($(buildsoc),a0v1)
$(NAME)_CFLAGS += -DLEGA_A0V1
GLOBAL_LDS_FILES += $(SOURCE_ROOT)/board/asr5501/gcc.ld
else
$(NAME)_CFLAGS += -DLEGA_A0V2
GLOBAL_LDS_FILES += $(SOURCE_ROOT)/board/asr5501/gcc_a0v2.ld
endif
CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_LEGAWIFI
CONFIG_SYSINFO_DEVICE_NAME := 5501A0V240A
GLOBAL_DEFINES += STDIO_UART=1
GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\"
GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\"
GLOBAL_CFLAGS += -DLEGA_CM4
GLOBAL_CFLAGS += -DAWSS_REGISTRAR_LOWPOWER_EN
EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_ota_bin.mk
#GLOBAL_DEFINES += CONFIG_SOCKET_ACCESS_CONTROL
GLOBAL_CFLAGS += -DCONFIG_TCP_SOCKET_ACCESS_CONTROL

Binary file not shown.

View file

@ -0,0 +1,21 @@
#ifndef __BOARD_H__
#define __BOARD_H__
#include "hal/hal.h"
extern hal_logic_partition_t hal_partitions[];
extern void flash_partition_init(void);
typedef enum {
PORT_UART_STD,
PORT_UART_AT,
PORT_UART_RS485,
PORT_UART_SCANNER,
PORT_UART_LORA,
PORT_UART_TEMP,
PORT_UART_SIZE,
PORT_UART_INVALID = 255
}PORT_UART_TYPE;
#endif //__BOARD_H__

View file

@ -0,0 +1,232 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <k_api.h>
#include <assert.h>
#include <stdio.h>
#include <sys/time.h>
#if (RHINO_CONFIG_HW_COUNT > 0)
void soc_hw_timer_init(void)
{
}
hr_timer_t soc_hr_hw_cnt_get(void)
{
return 0;
//return *(volatile uint64_t *)0xc0000120;
}
lr_timer_t soc_lr_hw_cnt_get(void)
{
return 0;
}
#endif /* RHINO_CONFIG_HW_COUNT */
#if (RHINO_CONFIG_INTRPT_GUARD > 0)
void soc_intrpt_guard(void)
{
}
#endif
#if (RHINO_CONFIG_INTRPT_STACK_REMAIN_GET > 0)
size_t soc_intrpt_stack_remain_get(void)
{
return 0;
}
#endif
#if (RHINO_CONFIG_INTRPT_STACK_OVF_CHECK > 0)
void soc_intrpt_stack_ovf_check(void)
{
}
#endif
#if (RHINO_CONFIG_MM_TLF > 0)
#if defined (__CC_ARM) /* Keil / armcc */
#define HEAP_BUFFER_SIZE 1024*120
uint8_t g_heap_buf[HEAP_BUFFER_SIZE];
k_mm_region_t g_mm_region[] = {{g_heap_buf, HEAP_BUFFER_SIZE}};
#elif defined (__ICCARM__)/* IAR */
#define HEAP_BUFFER_SIZE 1024*120
uint8_t g_heap_buf[HEAP_BUFFER_SIZE];
k_mm_region_t g_mm_region[] = {{g_heap_buf, HEAP_BUFFER_SIZE}};
#else /* GCC */
extern void *heap_start;
extern void *heap_end;
extern void *heap_len;
/* heap_start and heap_len is set by linkscript(*.ld) */
k_mm_region_t g_mm_region[] = {{(uint8_t*)&heap_start,(size_t)&heap_len}};
#endif
int g_region_num = sizeof(g_mm_region)/sizeof(k_mm_region_t);
#endif
#if (RHINO_CONFIG_MM_LEAKCHECK > 0 )
extern int __bss_start__, __bss_end__, _sdata, _edata;
void aos_mm_leak_region_init(void)
{
#if (RHINO_CONFIG_MM_DEBUG > 0)
krhino_mm_leak_region_init(&__bss_start__, &__bss_end__);
krhino_mm_leak_region_init(&_sdata, &_edata);
#endif
}
#endif
#if (RHINO_CONFIG_TASK_STACK_CUR_CHECK > 0)
size_t soc_get_cur_sp()
{
size_t sp = 0;
#if defined (__GNUC__)&&!defined(__CC_ARM)
asm volatile(
"mov %0,sp\n"
:"=r"(sp));
#endif
return sp;
}
static void soc_print_stack()
{
void *cur, *end, *start;
int stack_size;
int i=0;
int *p;
ktask_t * cur_task;
cur_task = krhino_cur_task_get();
start = cur_task->task_stack_base;
stack_size = cur_task->stack_size;
end = start + stack_size*4;
cur = (void *)soc_get_cur_sp();
p = (int*)cur;
while(p < (int*)end) {
if(i%4==0) {
printf("\r\n%08lx:",(uint32_t)p);
}
printf("%08x ", *p);
i++;
p++;
}
printf("=============,task_name:%s,start:%x,stack:%x,cur:%x\r\n", cur_task->task_name, (unsigned int)start, stack_size, (unsigned int)cur);
return;
}
#endif
void soc_err_proc(kstat_t err)
{
(void)err;
#if (RHINO_CONFIG_TASK_STACK_CUR_CHECK > 0)
soc_print_stack();
#endif
assert(0);
}
#if (RHINO_CONFIG_USER_HOOK > 0)
/**
* This function will provide init hook
*/
void krhino_init_hook(void)
{
return;
}
/**
* This function will provide system start hook
*/
void krhino_start_hook(void)
{
return;
}
/**
* This function will provide task create hook
* @param[in] task pointer to the task
*/
void krhino_task_create_hook(ktask_t *task)
{
return;
}
/**
* This function will provide task delete hook
* @param[in] task pointer to the task
*/
void krhino_task_del_hook(ktask_t *task, res_free_t *arg)
{
return;
}
/**
* This function will provide task abort hook
* @param[in] task pointer to the task
*/
void krhino_task_abort_hook(ktask_t *task)
{
return;
}
/**
* This function will provide task switch hook
*/
void krhino_task_switch_hook(ktask_t *orgin, ktask_t *dest)
{
return;
}
/**
* This function will provide system tick hook
*/
void krhino_tick_hook(void)
{
return;
}
/**
* This function will provide idle pre hook
*/
void krhino_idle_pre_hook(void)
{
return;
}
/**
* This function will provide idle hook
*/
void krhino_idle_hook(void)
{
extern void pmu_idle_hook(void);
pmu_idle_hook();
}
/**
* This function will provide krhino_mm_alloc hook
*/
void krhino_mm_alloc_hook(void *mem, size_t size)
{
return;
}
#endif
#if (RHINO_CONFIG_TRACE == 0)
void trace_start(void)
{
printf("trace config close!!!\r\n");
}
#endif
krhino_err_proc_t g_err_proc = soc_err_proc;

View file

@ -0,0 +1,150 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef K_CONFIG_H
#define K_CONFIG_H
/* kernel feature conf */
#ifndef RHINO_CONFIG_SEM
#define RHINO_CONFIG_SEM 1
#endif
#ifndef RHINO_CONFIG_QUEUE
#define RHINO_CONFIG_QUEUE 1
#endif
#ifndef RHINO_CONFIG_TASK_SEM
#define RHINO_CONFIG_TASK_SEM 0
#endif
#ifndef RHINO_CONFIG_EVENT_FLAG
#define RHINO_CONFIG_EVENT_FLAG 0
#endif
#ifndef RHINO_CONFIG_TIMER
#define RHINO_CONFIG_TIMER 1
#endif
#ifndef RHINO_CONFIG_BUF_QUEUE
#define RHINO_CONFIG_BUF_QUEUE 1
#endif
#ifndef RHINO_CONFIG_MM_BLK
#define RHINO_CONFIG_MM_BLK 1
#endif
#ifndef RHINO_CONFIG_MM_DEBUG
#define RHINO_CONFIG_MM_DEBUG 1
#endif
#ifndef RHINO_CONFIG_MM_TLF
#define RHINO_CONFIG_MM_TLF 1
#endif
/* kernel task conf */
#ifndef RHINO_CONFIG_TASK_SUSPEND
#define RHINO_CONFIG_TASK_SUSPEND 1
#endif
#ifndef RHINO_CONFIG_TASK_INFO
#define RHINO_CONFIG_TASK_INFO 1
#endif
#ifndef RHINO_CONFIG_TASK_DEL
#define RHINO_CONFIG_TASK_DEL 1
#endif
#ifndef RHINO_CONFIG_TASK_WAIT_ABORT
#define RHINO_CONFIG_TASK_WAIT_ABORT 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK
#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1
#endif
#ifndef RHINO_CONFIG_SCHED_RR
#define RHINO_CONFIG_SCHED_RR 1
#endif
#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT
#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50
#endif
#ifndef RHINO_CONFIG_PRI_MAX
#define RHINO_CONFIG_PRI_MAX 62
#endif
#ifndef RHINO_CONFIG_USER_PRI_MAX
#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2)
#endif
/* kernel workqueue conf */
#ifndef RHINO_CONFIG_WORKQUEUE
#define RHINO_CONFIG_WORKQUEUE 0
#endif
/* kernel mm_region conf */
#ifndef RHINO_CONFIG_MM_REGION_MUTEX
#define RHINO_CONFIG_MM_REGION_MUTEX 0
#endif
/* kernel timer&tick conf */
#ifndef RHINO_CONFIG_TICKS_PER_SECOND
#define RHINO_CONFIG_TICKS_PER_SECOND 1000
#endif
/*must reserve enough stack size for timer cb will consume*/
#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE
#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 512
#endif
#ifndef RHINO_CONFIG_TIMER_TASK_PRI
#define RHINO_CONFIG_TIMER_TASK_PRI 5
#endif
#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK
#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0
#endif
/* kernel dyn alloc conf */
#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC
#define RHINO_CONFIG_KOBJ_DYN_ALLOC 1
#endif
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
#ifndef RHINO_CONFIG_K_DYN_TASK_STACK
#define RHINO_CONFIG_K_DYN_TASK_STACK 128
#endif
#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI
#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 6
#endif
#endif
/* kernel idle conf */
#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE
#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200
#endif
/* kernel hook conf */
#ifndef RHINO_CONFIG_USER_HOOK
#define RHINO_CONFIG_USER_HOOK 0
#endif
/* kernel stats conf */
#ifndef RHINO_CONFIG_SYSTEM_STATS
#define RHINO_CONFIG_SYSTEM_STATS 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK
#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 1
#endif
#ifndef RHINO_CONFIG_CPU_NUM
#define RHINO_CONFIG_CPU_NUM 1
#endif
/* lowpower conf */
#ifndef WIFI_CONFIG_SUPPORT_LOWPOWER
#define WIFI_CONFIG_SUPPORT_LOWPOWER 0
#endif
#ifndef WIFI_CONFIG_LISTENSET_BINIT
#define WIFI_CONFIG_LISTENSET_BINIT 0
#endif
#ifndef WIFI_CONFIG_LISTEN_INTERVAL
#define WIFI_CONFIG_LISTEN_INTERVAL 1
#endif
#ifndef WIFI_CONFIG_RECEIVE_DTIM
#define WIFI_CONFIG_RECEIVE_DTIM 1
#endif
#ifndef RHINO_CONFIG_GCC_RETADDR
#define RHINO_CONFIG_GCC_RETADDR 1
#endif
#endif /* K_CONFIG_H */

View file

@ -0,0 +1,47 @@
#include <aos/aos.h>
#include "hal/soc/soc.h"
#include "lega_flash.h"
/* Logic partition on flash devices */
hal_logic_partition_t hal_partitions[HAL_PARTITION_MAX];
extern const lega_logic_partition_t lega_partitions[];
void flash_partition_init(void)
{
hal_partitions[HAL_PARTITION_BOOTLOADER].partition_owner = lega_partitions[PARTITION_BOOTLOADER].partition_owner;
hal_partitions[HAL_PARTITION_BOOTLOADER].partition_description = lega_partitions[PARTITION_BOOTLOADER].partition_description;
hal_partitions[HAL_PARTITION_BOOTLOADER].partition_start_addr = lega_partitions[PARTITION_BOOTLOADER].partition_start_addr;
hal_partitions[HAL_PARTITION_BOOTLOADER].partition_length = lega_partitions[PARTITION_BOOTLOADER].partition_length;
hal_partitions[HAL_PARTITION_BOOTLOADER].partition_options = lega_partitions[PARTITION_BOOTLOADER].partition_options ;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_owner = lega_partitions[PARTITION_PARAMETER_1].partition_owner;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_description = lega_partitions[PARTITION_PARAMETER_1].partition_description;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_start_addr = lega_partitions[PARTITION_PARAMETER_1].partition_start_addr;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_length = lega_partitions[PARTITION_PARAMETER_1].partition_length;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_options = lega_partitions[PARTITION_PARAMETER_1].partition_options ;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_owner = lega_partitions[PARTITION_PARAMETER_2].partition_owner ;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_description = lega_partitions[PARTITION_PARAMETER_2].partition_description;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_start_addr = lega_partitions[PARTITION_PARAMETER_2].partition_start_addr;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_length = lega_partitions[PARTITION_PARAMETER_2].partition_length;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_options = lega_partitions[PARTITION_PARAMETER_2].partition_options;
hal_partitions[HAL_PARTITION_PARAMETER_3].partition_owner = lega_partitions[PARTITION_PARAMETER_3].partition_owner ;
hal_partitions[HAL_PARTITION_PARAMETER_3].partition_description = lega_partitions[PARTITION_PARAMETER_3].partition_description;
hal_partitions[HAL_PARTITION_PARAMETER_3].partition_start_addr = lega_partitions[PARTITION_PARAMETER_3].partition_start_addr;
hal_partitions[HAL_PARTITION_PARAMETER_3].partition_length = lega_partitions[PARTITION_PARAMETER_3].partition_length;
hal_partitions[HAL_PARTITION_PARAMETER_3].partition_options = lega_partitions[PARTITION_PARAMETER_3].partition_options;
hal_partitions[HAL_PARTITION_APPLICATION].partition_owner = lega_partitions[PARTITION_APPLICATION].partition_owner;
hal_partitions[HAL_PARTITION_APPLICATION].partition_description = lega_partitions[PARTITION_APPLICATION].partition_description;
hal_partitions[HAL_PARTITION_APPLICATION].partition_start_addr = lega_partitions[PARTITION_APPLICATION].partition_start_addr;
hal_partitions[HAL_PARTITION_APPLICATION].partition_length = lega_partitions[PARTITION_APPLICATION].partition_length;
hal_partitions[HAL_PARTITION_APPLICATION].partition_options = lega_partitions[PARTITION_APPLICATION].partition_options;
hal_partitions[HAL_PARTITION_OTA_TEMP].partition_owner = lega_partitions[PARTITION_OTA_TEMP].partition_owner;
hal_partitions[HAL_PARTITION_OTA_TEMP].partition_description = lega_partitions[PARTITION_OTA_TEMP].partition_description;
hal_partitions[HAL_PARTITION_OTA_TEMP].partition_start_addr = lega_partitions[PARTITION_OTA_TEMP].partition_start_addr;
hal_partitions[HAL_PARTITION_OTA_TEMP].partition_length = lega_partitions[PARTITION_OTA_TEMP].partition_length;
hal_partitions[HAL_PARTITION_OTA_TEMP].partition_options = lega_partitions[PARTITION_OTA_TEMP].partition_options;
}

View file

@ -0,0 +1,13 @@
FUNC void Setup (void) {
SP = _RDWORD(0x10040000); // Setup Stack Pointer
PC = _RDWORD(0x10040004); // Setup Program Counter
_WDWORD(0xE000ED08, 0x10040000); // Setup Vector Table Offset Register
}
load ./Objects/linkkitapp@asr5501.elf incremental
Setup(); // Setup for Running
g, main

View file

@ -0,0 +1,617 @@
/*
* Copyright (C) 2015-2018 ASR Group Holding Limited
*/
#ifndef __LEGARTOS_H__
#define __LEGARTOS_H__
#include <k_api.h>
#include <ctype.h>
#include "port.h"
#define LEGA_NEVER_TIMEOUT (0xFFFFFFFF)
#define LEGA_WAIT_FOREVER (0xFFFFFFFF)
#define LEGA_NO_WAIT (0)
typedef enum
{
kNoErr=0,
kGeneralErr,
kTimeoutErr,
}OSStatus;
typedef enum
{
FALSE=0,
TRUE=1,
}OSBool;
typedef void * lega_semaphore_t;
typedef void * lega_mutex_t;
typedef void * lega_thread_t;
typedef void * lega_queue_t;
//typedef void * lega_event_t;// LEGA OS event: lega_semaphore_t, lega_mutex_t or lega_queue_t
typedef void (*timer_handler_t)( void* arg );
//typedef OSStatus (*event_handler_t)( void* arg );
typedef struct
{
void * handle;
timer_handler_t function;
void * arg;
}lega_timer_t;
typedef uint32_t lega_thread_arg_t;
typedef void (*lega_thread_function_t)( lega_thread_arg_t arg );
/** @defgroup LEGA_RTOS_Thread LEGA RTOS Thread Management Functions
* @brief Provide thread creation, delete, suspend, resume, and other RTOS management API
* @verbatim
* LEGA thread priority table
*
* +----------+-----------------+
* | Priority | Thread |
* |----------|-----------------|
* | 0 | LEGA | Highest priority
* | 1 | Network |
* | 2 | |
* | 3 | Network worker |
* | 4 | |
* | 5 | Default Library |
* | | Default worker |
* | 6 | |
* | 7 | Application |
* | 8 | |
* | 9 | Idle | Lowest priority
* +----------+-----------------+
* @endverbatim
* @{
*/
OSBool lega_rtos_is_in_interrupt_context(void);
/** @brief Creates and starts a new thread
*
* @param thread : Pointer to variable that will receive the thread handle (can be null)
* @param priority : A priority number.
* @param name : a text name for the thread (can be null)
* @param function : the main thread function
* @param stack_size : stack size for this thread
* @param arg : argument which will be passed to thread function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_create_thread( lega_thread_t* thread, uint8_t priority, const char* name, lega_thread_function_t function, uint32_t stack_size, lega_thread_arg_t arg );
/** @brief Deletes a terminated thread
*
* @param thread : the handle of the thread to delete, , NULL is the current thread
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_delete_thread( lega_thread_t* thread );
/** @defgroup LEGA_RTOS_SEM LEGA RTOS Semaphore Functions
* @brief Provide management APIs for semaphore such as init,set,get and dinit.
* @{
*/
/** @brief Initialises a counting semaphore and set count to 0
*
* @param semaphore : a pointer to the semaphore handle to be initialised
* @param count : the max count number of this semaphore
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_init_semaphore( lega_semaphore_t* semaphore, int count );
/** @brief Set (post/put/increment) a semaphore
*
* @param semaphore : a pointer to the semaphore handle to be set
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_set_semaphore( lega_semaphore_t* semaphore );
/** @brief Get (wait/decrement) a semaphore
*
* @Details Attempts to get (wait/decrement) a semaphore. If semaphore is at zero already,
* then the calling thread will be suspended until another thread sets the
* semaphore with @ref lega_rtos_set_semaphore
*
* @param semaphore : a pointer to the semaphore handle
* @param timeout_ms: the number of milliseconds to wait before returning
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_get_semaphore( lega_semaphore_t* semaphore, uint32_t timeout_ms );
/** @brief De-initialise a semaphore
*
* @Details Deletes a semaphore created with @ref lega_rtos_init_semaphore
*
* @param semaphore : a pointer to the semaphore handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_deinit_semaphore( lega_semaphore_t* semaphore );
/**
* @}
*/
#define lega_rtos_declare_critical() CPSR_ALLOC()
/** @brief Enter a critical session, all interrupts are disabled
*
* @return none
*/
#define lega_rtos_enter_critical() RHINO_CRITICAL_ENTER()
//void lega_rtos_enter_critical( void );
/** @brief Exit a critical session, all interrupts are enabled
*
* @return none
*/
#define lega_rtos_exit_critical() RHINO_CRITICAL_EXIT()
//void lega_rtos_exit_critical( void );
/** @defgroup LEGA_RTOS_MUTEX LEGA RTOS Mutex Functions
* @brief Provide management APIs for Mutex such as init,lock,unlock and dinit.
* @{
*/
/** @brief Initialises a mutex
*
* @Details A mutex is different to a semaphore in that a thread that already holds
* the lock on the mutex can request the lock again (nested) without causing
* it to be suspended.
*
* @param mutex : a pointer to the mutex handle to be initialised
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_init_mutex( lega_mutex_t* mutex );
/** @brief Obtains the lock on a mutex
*
* @Details Attempts to obtain the lock on a mutex. If the lock is already held
* by another thead, the calling thread will be suspended until the mutex
* lock is released by the other thread.
*
* @param mutex : a pointer to the mutex handle to be locked
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_lock_mutex( lega_mutex_t* mutex, uint32_t timeout_ms );
/** @brief Releases the lock on a mutex
*
* @Details Releases a currently held lock on a mutex. If another thread
* is waiting on the mutex lock, then it will be resumed.
*
* @param mutex : a pointer to the mutex handle to be unlocked
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_unlock_mutex( lega_mutex_t* mutex );
/** @brief De-initialise a mutex
*
* @Details Deletes a mutex created with @ref lega_rtos_init_mutex
*
* @param mutex : a pointer to the mutex handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_deinit_mutex( lega_mutex_t* mutex );
/**
* @}
*/
/** @defgroup LEGA_RTOS_QUEUE LEGA RTOS FIFO Queue Functions
* @brief Provide management APIs for FIFO such as init,push,pop and dinit.
* @{
*/
/** @brief Initialises a FIFO queue
*
* @param queue : a pointer to the queue handle to be initialised
* @param name : a text string name for the queue (NULL is allowed)
* @param message_size : size in bytes of objects that will be held in the queue
* @param number_of_messages : depth of the queue - i.e. max number of objects in the queue
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_init_queue( lega_queue_t* queue, const char* name, uint32_t message_size, uint32_t number_of_messages );
/** @brief Pushes an object onto a queue
*
* @param queue : a pointer to the queue handle
* @param message : the object to be added to the queue. Size is assumed to be
* the size specified in @ref lega_rtos_init_queue
* @param timeout_ms: the number of milliseconds to wait before returning
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error or timeout occurred
*/
OSStatus lega_rtos_push_to_queue( lega_queue_t* queue, void* message, uint32_t timeout_ms );
/** @brief Pops an object off a queue
*
* @param queue : a pointer to the queue handle
* @param message : pointer to a buffer that will receive the object being
* popped off the queue. Size is assumed to be
* the size specified in @ref lega_rtos_init_queue , hence
* you must ensure the buffer is long enough or memory
* corruption will result
* @param timeout_ms: the number of milliseconds to wait before returning
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error or timeout occurred
*/
OSStatus lega_rtos_pop_from_queue( lega_queue_t* queue, void* message, uint32_t timeout_ms );
/** @brief De-initialise a queue created with @ref lega_rtos_init_queue
*
* @param queue : a pointer to the queue handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_deinit_queue( lega_queue_t* queue );
/** @brief Check if a queue is empty
*
* @param queue : a pointer to the queue handle
*
* @return true : queue is empty.
* @return false : queue is not empty.
*/
OSBool lega_rtos_is_queue_empty( lega_queue_t* queue );
/** @brief Check if a queue is full
*
* @param queue : a pointer to the queue handle
*
* @return true : queue is empty.
* @return false : queue is not empty.
*/
OSBool lega_rtos_is_queue_full( lega_queue_t* queue );
/**
* @}
*/
/** @defgroup LEGA_RTOS_TIMER LEGA RTOS Timer Functions
* @brief Provide management APIs for timer such as init,start,stop,reload and dinit.
* @{
*/
/**
* @brief Initialize a RTOS timer
*
* @note Timer does not start running until @ref lega_start_timer is called
*
* @param timer : a pointer to the timer handle to be initialised
* @param time_ms : Timer period in milliseconds
* @param function : the callback handler function that is called each time the
* timer expires
* @param arg : an argument that will be passed to the callback function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_init_timer( lega_timer_t* timer, uint32_t time_ms, timer_handler_t function, void* arg );
/** @brief Starts a RTOS timer running
*
* @note Timer must have been previously initialised with @ref lega_rtos_init_timer
*
* @param timer : a pointer to the timer handle to start
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_start_timer( lega_timer_t* timer );
/** @brief Stops a running RTOS timer
*
* @note Timer must have been previously started with @ref lega_rtos_init_timer
*
* @param timer : a pointer to the timer handle to stop
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_stop_timer( lega_timer_t* timer );
/** @brief Reloads a RTOS timer that has expired
*
* @note This is usually called in the timer callback handler, to
* reschedule the timer for the next period.
*
* @param timer : a pointer to the timer handle to reload
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_reload_timer( lega_timer_t* timer );
/** @brief De-initialise a RTOS timer
*
* @note Deletes a RTOS timer created with @ref lega_rtos_init_timer
*
* @param timer : a pointer to the RTOS timer handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_deinit_timer( lega_timer_t* timer );
/** @brief Check if an RTOS timer is running
*
* @param timer : a pointer to the RTOS timer handle
*
* @return true : if running.
* @return false : if not running
*/
OSBool lega_rtos_is_timer_running( lega_timer_t* timer );
/**
* @brief Gets time in miiliseconds since RTOS start
*
* @note: Since this is only 32 bits, it will roll over every 49 days, 17 hours.
*
* @returns Time in milliseconds since RTOS started.
*/
uint32_t lega_rtos_get_time(void);
/**
* @}
*/
/** @brief Suspend current thread for a specific time
*
* @param num_ms : A time interval (Unit: millisecond)
*
* @return kNoErr.
*/
OSStatus lega_rtos_delay_milliseconds( uint32_t num_ms );
#define lega_rtos_malloc(s) _lega_rtos_malloc(s,__FUNCTION__,__LINE__)
void *_lega_rtos_malloc(uint32_t xWantedSize,const char * function,uint32_t line);
void lega_rtos_free(void *mem);
void lega_system_reset();
#if 0
/** @brief Creates a worker thread
*
* Creates a worker thread
* A worker thread is a thread in whose context timed and asynchronous events
* execute.
*
* @param worker_thread : a pointer to the worker thread to be created
* @param priority : thread priority
* @param stack_size : thread's stack size in number of bytes
* @param event_queue_size : number of events can be pushed into the queue
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_create_worker_thread( lega_worker_thread_t* worker_thread, uint8_t priority, uint32_t stack_size, uint32_t event_queue_size );
/** @brief Deletes a worker thread
*
* @param worker_thread : a pointer to the worker thread to be created
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_delete_worker_thread( lega_worker_thread_t* worker_thread );
/** @brief Suspend a thread
*
* @param thread : the handle of the thread to suspend, NULL is the current thread
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
void lega_rtos_suspend_thread(lega_thread_t* thread);
/** @brief Suspend all other thread
*
* @param none
*
* @return none
*/
void lega_rtos_suspend_all_thread(void);
/** @brief Rresume all other thread
*
* @param none
*
* @return none
*/
long lega_rtos_resume_all_thread(void);
/** @brief Sleeps until another thread has terminated
*
* @Details Causes the current thread to sleep until the specified other thread
* has terminated. If the processor is heavily loaded with higher priority
* tasks, this thread may not wake until significantly after the thread termination.
*
* @param thread : the handle of the other thread which will terminate
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_thread_join( lega_thread_t* thread );
/** @brief Forcibly wakes another thread
*
* @Details Causes the specified thread to wake from suspension. This will usually
* cause an error or timeout in that thread, since the task it was waiting on
* is not complete.
*
* @param thread : the handle of the other thread which will be woken
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_thread_force_awake( lega_thread_t* thread );
/** @brief Checks if a thread is the current thread
*
* @Details Checks if a specified thread is the currently running thread
*
* @param thread : the handle of the other thread against which the current thread
* will be compared
*
* @return true : specified thread is the current thread
* @return false : specified thread is not currently running
*/
OSBool lega_rtos_is_current_thread( lega_thread_t* thread );
/** @brief Print Thread status into buffer
*
* @param buffer, point to buffer to store thread status
* @param length, length of the buffer
*
* @return none
*/
OSStatus lega_rtos_print_thread_status( char* buffer, int length );
/**
* @}
*/
/** @defgroup LEGA_RTOS_EVENT LEGA RTOS Event Functions
* @{
*/
/**
* @brief Sends an asynchronous event to the associated worker thread
*
* @param worker_thread :the worker thread in which context the callback should execute from
* @param function : the callback function to be called from the worker thread
* @param arg : the argument to be passed to the callback function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_send_asynchronous_event( lega_worker_thread_t* worker_thread, event_handler_t function, void* arg );
/** Requests a function be called at a regular interval
*
* This function registers a function that will be called at a regular
* interval. Since this is based on the RTOS time-slice scheduling, the
* accuracy is not high, and is affected by processor load.
*
* @param event_object : pointer to a event handle which will be initialised
* @param worker_thread : pointer to the worker thread in whose context the
* callback function runs on
* @param function : the callback function that is to be called regularly
* @param time_ms : the time period between function calls in milliseconds
* @param arg : an argument that will be supplied to the function when
* it is called
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_register_timed_event( lega_timed_event_t* event_object, lega_worker_thread_t* worker_thread, event_handler_t function, uint32_t time_ms, void* arg );
/** Removes a request for a regular function execution
*
* This function de-registers a function that has previously been set-up
* with @ref lega_rtos_register_timed_event.
*
* @param event_object : the event handle used with @ref lega_rtos_register_timed_event
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
OSStatus lega_rtos_deregister_timed_event( lega_timed_event_t* event_object );
/**
* @}
*/
int SetTimer(unsigned long ms, void (*psysTimerHandler)(void));
int SetTimer_uniq(unsigned long ms, void (*psysTimerHandler)(void));
int UnSetTimer(void (*psysTimerHandler)(void));
/** @brief Initialize an endpoint for a RTOS event, a file descriptor
* will be created, can be used for select
*
* @param event_handle : lega_semaphore_t, lega_mutex_t or lega_queue_t
*
* @retval On success, a file descriptor for RTOS event is returned.
* On error, -1 is returned.
*/
int lega_rtos_init_event_fd(lega_event_t event_handle);
/** @brief De-initialise an endpoint created from a RTOS event
*
* @param fd : file descriptor for RTOS event
*
* @retval 0 for success. On error, -1 is returned.
*/
int lega_rtos_deinit_event_fd(int fd);
/**
* @}
*/
#endif
#endif //__LEGARTOS_H__

View file

@ -0,0 +1,452 @@
/**
****************************************************************************************
*
* @file lega_wifi_api.h
*
* @brief WiFi API.
*
* Copyright (C) ASR
*
****************************************************************************************
*/
#ifndef _LEGA_WIFI_API_H_
#define _LEGA_WIFI_API_H_
#include <stdint.h>
#include "lega_cm4.h"
/**
* @brief wlan network interface enumeration definition.
*/
typedef enum {
SOFTAP, /*Act as an access point, and other station can connect, 4 stations Max*/
STA, /*Act as a station which can connect to an access point*/
} lega_wlan_type_e;
enum {
WLAN_DHCP_DISABLE = 0,
WLAN_DHCP_CLIENT,
WLAN_DHCP_SERVER,
};
typedef enum {
EVENT_STATION_UP = 1, /*used in station mode,
indicate station associated in open mode or 4-way-handshake done in WPA/WPA2*/
EVENT_STATION_DOWN, /*used in station mode, indicate station deauthed*/
EVENT_AP_UP, /*used in softap mode, indicate softap enabled*/
EVENT_AP_DOWN, /*used in softap mode, indicate softap disabled*/
} lega_wifi_event_e;
typedef enum {
CONNECT_SUCC,
CONNECT_SCAN_FAIL,
CONNECT_CONN_FAIL,
} lega_start_adv_results_e;
/**
* @brief Scan result using normal scan.
*/
typedef struct {
uint8_t is_scan_adv;
char ap_num; /**< The number of access points found in scanning. */
struct {
char ssid[32+1]; /*ssid max len:32. +1 is for '\0'. when ssidlen is 32 */
char ap_power; /**< Signal strength, min:0, max:100. */
char bssid[6]; /* The BSSID of an access point. */
char channel; /* The RF frequency, 1-13 */
uint8_t security; /* Security type, @ref wlan_sec_type_t */
} * ap_list;
} lega_wlan_scan_result_t;
typedef enum {
WLAN_SECURITY_OPEN, //NONE
WLAN_SECURITY_WEP, //WEP
WLAN_SECURITY_WPA, //WPA
WLAN_SECURITY_WPA2, //WPA2
WLAN_SECURITY_AUTO, //WPA or WPA2
WLAN_SECURITY_MAX,
} lega_wlan_security_e;
/*used in event callback of station mode, indicate softap informatino which is connected*/
typedef struct {
int rssi; /* rssi */
char ssid[32+1]; /* ssid max len:32. +1 is for '\0' when ssidlen is 32 */
char pwd[64+1]; /* pwd max len:64. +1 is for '\0' when pwdlen is 64 */
char bssid[6]; /* BSSID of the wlan needs to be connected.*/
char ssid_len; /*ssid length*/
char pwd_len; /*password length*/
char channel; /* wifi channel 0-13.*/
char security; /*refer to lega_wlan_security_e*/
} lega_wlan_ap_info_adv_t;
/*only used in station mode*/
typedef struct {
char dhcp; /* no use currently */
char macaddr[16]; /* mac address on the target wlan interface, ASCII*/
char ip[16]; /* Local IP address on the target wlan interface, ASCII*/
char gate[16]; /* Router IP address on the target wlan interface, ASCII */
char mask[16]; /* Netmask on the target wlan interface, ASCII*/
char dns[16]; /* no use currently , ASCII*/
char broadcastip[16]; /* no use currently , ASCII*/
} lega_wlan_ip_stat_t;
/*only used in station mode*/
typedef struct {
int is_connected; /* The link to wlan is established or not, 0: disconnected, 1: connected. */
int wifi_strength; /* Signal strength of the current connected AP */
char ssid[32+1]; /* ssid max len:32. +1 is for '\0'. when ssidlen is 32 */
char bssid[6]; /* BSSID of the current connected wlan */
int channel; /* Channel of the current connected wlan */
} lega_wlan_link_stat_t;
/*used in open cmd of hal_wifi_module_t*/
typedef struct {
char wifi_mode; /* refer to hal_wifi_type_t*/
char security; /* security mode */
char wifi_ssid[32]; /* in station mode, indicate SSID of the wlan needs to be connected.
in softap mode, indicate softap SSID*/
char wifi_key[64]; /* in station mode, indicate Security key of the wlan needs to be connected,
in softap mode, indicate softap password.(ignored in an open system.) */
char local_ip_addr[16]; /* used in softap mode to config ip for dut */
char net_mask[16]; /* used in softap mode to config gateway for dut */
char gateway_ip_addr[16]; /* used in softap mode to config netmask for dut */
char dns_server_ip_addr[16]; /* no use currently */
char dhcp_mode; /* no use currently */
char channel; /* softap channel in softap mode; connect channel in sta mode*/
char mac_addr[6]; /* connect bssid in sta mode*/
char reserved[32]; /* no use currently */
int wifi_retry_interval; /* no use currently */
int interval; /* used in softap mode to config beacon listen interval */
int hide; /* used in softap mode to config hidden SSID */
} lega_wlan_init_type_t;
/** @brief wifi init functin, user should call it before use any wifi cmd
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_init(void);
/** @brief wifi deinit functin, call it when donot use wifi any more to free resources
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_deinit(void);
/** @brief used in station and softap mode, open wifi cmd
*
* @param init_info : refer to lega_wlan_init_type_t
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_open(lega_wlan_init_type_t* init_info);
/** @brief used in station and softap mode, close wifi cmd
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_close(void);
/** @brief used in station mode, scan cmd
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_start_scan(void);
/** @brief used in station mode, scan cmd
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_start_scan_adv(void);
/** @brief used in station mode, scan cmd
*
* @param ssid : target ssid to scan
* @param is_scan_advance :scan to get bssid, channel and security
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_start_scan_active(const char *ssid, uint8_t is_scan_advance);
/** @brief used in station and softap mode, get mac address(in hex mode) of WIFI device
*
* @param mac_addr : pointer to get the mac address
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_get_mac_address(uint8_t *mac_addr);
/** @brief used in station and softap mode, set mac address for WIFI device
*
* @param mac_addr : src mac address pointer to set
*
*/
void lega_wlan_set_mac_address(uint8_t *mac_addr);
/** @brief used in station mode, get the ip information
*
* @param void
* @return NULL : error occurred.
* @return pointer : ip status got.
*/
lega_wlan_ip_stat_t * lega_wlan_get_ip_status(void);
/** @brief used in station mode, get link status information
*
* @param link_status : refer to lega_wlan_link_stat_t
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_get_link_status(lega_wlan_link_stat_t *link_status);
/** @brief used in station mode, get the associated ap information
*
* @param void
* @return NULL : error occurred.
* @return pointer : associated ap info got.
*/
lega_wlan_ap_info_adv_t *lega_wlan_get_associated_apinfo(void);
/*used in sniffer mode, open sniffer mode
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_start_monitor(void);
/*used in sniffer mode, close sniffer mode
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_stop_monitor(void);
/** @brief used in sniffer mode, set the sniffer channel, should call this cmd after call start_monitor cmd
*
* @param channel : WIFI channel(1-13)
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_monitor_set_channel(int channel);
/** @brief used to get current channel both in sta and ap mode
*
* @return 1-14 : channel number.
* @return 0 : no valid channel
*/
int lega_wlan_get_channel(void);
/** @brief used in sta mode, set the ps bc mc and listen interval, called before connect to ap.
*
* @param listen_bc_mc : true or false
* @param listen_interval :1, 3, 10
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_set_ps_options(uint8_t listen_bc_mc, uint16_t listen_interval);
/** @brief used in sta mode, set ps mode on/off
*
* @param ps_on : true or false
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_set_ps_mode(uint8_t ps_on);
/*when use monitor mode, user should register this type of callback function to get the received MPDU*/
typedef void (*monitor_cb_t)(uint8_t*data, int len, int rssi);
/*when use monitor-ap mode, user should register this type of callback function */
typedef void (*monitor_ap_cb_t)();
/** @brief used in sniffer mode, callback function to get received MPDU, should register before start_monitor
*
* @param fn : refer to monitor_data_cb_t
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_register_monitor_cb(monitor_cb_t fn);
/** @brief used in sniffer-ap mode, callback function for application
*
* @param fn : refer to monitor_ap_cb_t
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_register_monitor_ap_cb(monitor_ap_cb_t fn);
/* start adv callback function, notify the connect results*/
typedef void (*start_adv_cb_t)(lega_start_adv_results_e status);
/** @brief used in sta mode, callback function to notify the connecting results
*
* @param fn : refer to start_adv_cb_t
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_register_start_adv_cb(start_adv_cb_t fn);
/** @brief used in station mode or sniffer mode, call this cmd to send a MPDU constructed by user
*
* @param buf : mac header pointer of the MPDU
* @param len : length of the MPDU
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_send_raw_frame(uint8_t *buf, int len);
/*enable WIFI stack log, will be output by uart
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_start_debug_mode(void);
/*disable WIFI stack log
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_stop_debug_mode(void);
/*
* The event callback function called at specific wifi events occurred by wifi stack.
* user should register these callback if want to use the informatin.
*
* @note For HAL implementors, these callbacks must be
* called under normal task context, not from interrupt.
*/
typedef void (*lega_wlan_cb_ip_got)(lega_wlan_ip_stat_t *ip_status);
/** @brief used in station mode, WIFI stack call this cb when get ip
*
* @param fn : cb function type, refer to lega_wlan_ip_stat_t
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_ip_got_cb_register(lega_wlan_cb_ip_got fn);
typedef void (*lega_wlan_cb_stat_chg)(lega_wifi_event_e wlan_event);
/** @brief used in station and softap mode,
* WIFI stack call this cb when status change, refer to lega_wifi_event_e
*
* @param fn : cb function type
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_stat_chg_cb_register(lega_wlan_cb_stat_chg fn);
typedef void (*lega_wlan_cb_scan_compeleted)(lega_wlan_scan_result_t *result);
/** @brief used in station mode,
* WIFI stack call this cb when scan complete
*
* @param fn : cb function type
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_scan_compeleted_cb_register(lega_wlan_cb_scan_compeleted fn);
typedef void (*lega_wlan_cb_associated_ap)(lega_wlan_ap_info_adv_t *ap_info);
/** @brief used in station mode,
* WIFI stack call this cb when associated with an AP, and tell the AP information
*
* @param fn : cb function type
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_associated_ap_cb_register(lega_wlan_cb_associated_ap fn);
/** @brief calibration RCO clock for RTC
*
*/
void lega_drv_rco_cal(void);
/** @brief config to close DCDC PFM mode
*
*/
void lega_drv_close_dcdc_pfm(void);
/** @brief config to support smartconfig in MIMO scenario
*
*/
void lega_wlan_smartconfig_mimo_enable(void);
/** @brief set country code to update country code, different country may have different channel list
* called after hal_wifi_init
*/
void lega_wlan_set_country_code(char *country);
/** @brief start monitor and ap coexist mode
*
* @param init_info : refer to lega_wlan_init_type_t
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_start_monitor_ap(lega_wlan_init_type_t* init_info);
/** @brief stop monitor and ap coexist mode
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_stop_monitor_ap();
/** @brief get current temperature (C degree)
* called after hal_wifi_init
*
* @param p_temp : input param to get temperature, memory managed by caller
*
* @return 0 : on success.
* @return other : error occurred
*/
int16_t lega_rf_get_temperature(int16_t *p_temp);
/* temperature get callback function, notify the current temperature*/
typedef void (*temperature_get_cb_t)(int16_t temperature);
/** @brief set the timer to get temperature (in second)
* called after hal_wifi_init
*
* @param timer_in_sec : the timer in second
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_set_temperature_get_timer(uint64_t timer_in_sec);
/** @brief register the temperature get callback function
* called after hal_wifi_init
*
* @param func : the function will called to notify the temperature.
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_register_temperature_get_cb(temperature_get_cb_t func);
/* efuse info update callback function, pass customer efuse info to ASR*/
typedef void (*efuse_info_update_cb_t)(efuse_info_t *efuse_info);
/** @brief register the efuse info update callback function if efuse layout not same as ASR
* called before hal_wifi_init
*
* @param func : the function will be called to pass customer efuse info to ASR.
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_register_efuse_info_update_cb(efuse_info_update_cb_t func);
#endif //_LEGA_WIFI_API_H_

View file

@ -0,0 +1,64 @@
#ifndef _LEGA_WIFI_API_AOS_H_
#define _LEGA_WIFI_API_AOS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "lega_wlan_api.h"
typedef enum
{
WLAN_EVENT_SCAN_COMPLETED,
WLAN_EVENT_ASSOCIATED,
WLAN_EVENT_CONNECTED,
WLAN_EVENT_IP_GOT,
WLAN_EVENT_DISCONNECTED,
WLAN_EVENT_AP_UP,
WLAN_EVENT_AP_DOWN,
WLAN_EVENT_MAX,
}lega_wlan_event_e;
/**
* @brief Input network precise paras in lega_wlan_start_adv function.
*/
typedef struct
{
lega_wlan_ap_info_adv_t ap_info; /**< @ref apinfo_adv_t. */
char key[64]; /**< Security key or PMK of the wlan. */
int key_len; /**< The length of the key. */
char local_ip_addr[16]; /**< Static IP configuration, Local IP address. */
char net_mask[16]; /**< Static IP configuration, Netmask. */
char gateway_ip_addr[16]; /**< Static IP configuration, Router IP address. */
char dns_server_ip_addr[16]; /**< Static IP configuration, DNS server IP address. */
char dhcp_mode; /**< DHCP mode, @ref DHCP_Disable, @ref DHCP_Client and @ref DHCP_Server. */
char reserved[32];
int wifi_retry_interval; /**< Retry interval if an error is occured when connecting an access point,
time unit is millisecond. */
} lega_wlan_init_info_adv_st;
/** @brief used in station and softap mode, get mac address(in char mode) of WIFI device
*
* @param mac_addr : pointer to get the mac address
*
* @return 0 : on success.
* @return other : error occurred
*/
int lega_wlan_get_mac_address_inchar(char *puc_mac);
int lega_wlan_suspend_sta(void);
int lega_wlan_suspend_ap(void);
int lega_wlan_suspend(void);
void lega_wlan_register_mgmt_monitor_cb(monitor_cb_t fn);
/*Wifi event callback interface
*
* @return void
*/
extern void wifi_event_cb(lega_wlan_event_e evt, void* info);
#ifdef __cplusplus
}
#endif
#endif //_LEGA_WIFI_API_AOS_H_

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CC_H__
#define __CC_H__
#include "stdio.h"
#include "stdlib.h"
#include <sys/time.h>
#define LWIP_MAILBOX_QUEUE 1
#define LWIP_TIMEVAL_PRIVATE 0
#define LWIP_NO_INTTYPES_H 1
#if LWIP_NO_INTTYPES_H
#define X8_F "02x"
#define U16_F "u"
#define S16_F "d"
#define X16_F "x"
#define U32_F "u"
#define S32_F "d"
#define X32_F "x"
#define SZT_F U32_F
#endif
/* define compiler specific symbols */
#if defined (__ICCARM__)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_USE_INCLUDES
#elif defined (__CC_ARM)
#define PACK_STRUCT_BEGIN __packed
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#elif defined (__GNUC__)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT __attribute__ ((packed))
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#elif defined (__TASKING__)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#endif
#ifndef LWIP_PLATFORM_ASSERT
#define LWIP_PLATFORM_ASSERT(x) \
do \
{ printf("Assertion \"%s\" failed at line %d in %s\n", x, __LINE__, __FILE__); \
} while(0)
#endif
#ifndef LWIP_PLATFORM_DIAG
#define LWIP_PLATFORM_DIAG(x) do {printf x ;} while(0)
#endif
// cup byte order
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#define LWIP_RAND() ((u32_t)rand())
#endif /* __CC_H__ */

View file

@ -0,0 +1,322 @@
/**
* @file
*
* lwIP Options Configuration
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_LWIPOPTS_H
#define LWIP_LWIPOPTS_H
#include "lwip/arch.h"
#define LWIP_NETIF_API 1
#define LWIP_PRIVATE_FD_SET
/**
* Include user defined options first. Anything not defined in these files
* will be set to standard values. Override anything you dont like!
*/
#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1
/*
-------------- NO SYS --------------
*/
#define NO_SYS 0
#define SYS_LIGHTWEIGHT_PROT (NO_SYS == 0)
#ifndef LWIP_NETIF_API
#define LWIP_NETIF_API 1
#endif
/*
---------- Memory options ----------
*/
#define MEM_ALIGNMENT 4
#define MEM_SIZE (3*1024) //(10*1024)
#define MEM_LIBC_MALLOC 1
#if MEM_LIBC_MALLOC
#include <aos/kernel.h>
#define mem_clib_malloc aos_malloc
#define mem_clib_free aos_free
#define mem_clib_calloc(n, m) aos_zalloc( (n) * (m) )
#endif
#define MEMP_MEM_MALLOC 1
#define MEMP_OVERFLOW_CHECK 1
/*
---------- Internal Memory Pool Sizes ----------
*/
#define MEMP_NUM_PBUF 8
#define MEMP_NUM_RAW_PCB 8
#define MEMP_NUM_UDP_PCB 8
#define MEMP_NUM_TCP_PCB 8
#define MEMP_NUM_TCP_PCB_LISTEN 8
#define MEMP_NUM_TCP_SEG 12
#define MEMP_NUM_REASSDATA 4
#define MEMP_NUM_FRAG_PBUF 8
#define MEMP_NUM_ARP_QUEUE 8
#define MEMP_NUM_NETBUF 8
#define MEMP_NUM_NETCONN 10
#define MEMP_NUM_TCPIP_MSG_API 8
#define MEMP_NUM_TCPIP_MSG_INPKT 12
#define PBUF_POOL_SIZE 10
/*
---------- ARP options ----------
*/
#define LWIP_ARP 1
/*
---------- IP options ----------
*/
#define LWIP_IPV4 1
#define LWIP_IPV6 0
#define IP_FORWARD 0
#define IP_OPTIONS_ALLOWED 1
#define IP_REASSEMBLY 0
#define IP_FRAG 0
#define IP_REASS_MAXAGE 3
#define IP_REASS_MAX_PBUFS 4
#define IP_FRAG_USES_STATIC_BUF 0
#define IP_DEFAULT_TTL 255
/*
---------- ICMP options ----------
*/
#define LWIP_ICMP 1
#define LWIP_ICMP6 1
#define CHECKSUM_CHECK_ICMP6 0
#define LWIP_MULTICAST_PING 1
/*
---------- RAW options ----------
*/
#define LWIP_RAW 1
/*
---------- DHCP options ----------
*/
#define LWIP_DHCP 1
#define LWIP_NETIF_STATUS_CALLBACK 1
#define DHCP_DOES_ARP_CHECK 0
/*
---------- AUTOIP options ----------
*/
#define LWIP_AUTOIP 0
/*
---------- SNMP options ----------
*/
#define LWIP_SNMP 0
/*
---------- IGMP options ----------
*/
#define LWIP_IGMP 1
/*
---------- DNS options -----------
*/
#define LWIP_DNS 1
/*
---------- UDP options ----------
*/
#define LWIP_UDP 1
/*
---------- TCP options ----------
*/
#define LWIP_TCP 1
#define LWIP_LISTEN_BACKLOG 0
#define TCP_MSS 1460 //1792
#define TCP_WND (2 * TCP_MSS)
#define TCP_SND_BUF (4 * TCP_MSS)
#define TCP_MAXRTX 12
#define TCP_SYNMAXRTX 12
/*
---------- Pbuf options ----------
*/
#define PBUF_LINK_HLEN 16
//#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN)
#define PBUF_POOL_BUFSIZE 512 //1500
/*
---------- Network Interfaces options ----------
*/
#ifdef CHECKSUM_BY_HARDWARE
/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 0
/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 0
/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 0
/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 0
/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 0
/* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 0
#define CHECKSUM_GEN_ICMP 0
#else
/* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 1
/* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 1
/* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 1
/* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 1
/* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 1
/* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 1
#endif
/*
---------- LOOPIF options ----------
*/
#define LWIP_NETIF_LOOPBACK 1
#define LWIP_HAVE_LOOPIF 1
#define LWIP_NETIF_LOOPBACK_MULTITHREADING 1
#define LWIP_LOOPBACK_MAX_PBUFS 8
/*
---------- Thread options ----------
*/
#define TCPIP_MBOX_SIZE 60
#define DEFAULT_ACCEPTMBOX_SIZE 10
#define DEFAULT_RAW_RECVMBOX_SIZE 10
#define DEFAULT_UDP_RECVMBOX_SIZE 20
#define DEFAULT_TCP_RECVMBOX_SIZE 10
#define LWIP_TCPIP_CORE_LOCKING 0
#define LWIP_TCPIP_CORE_LOCKING_INPUT 0
#define ETHIF_IN_TASK_STACKSIZE 512 /* unit 4 byte */
#define ETHIF_IN_TASK_PRIO 10
#define TCPIP_THREAD_STACKSIZE 2048//10240/* unit 4 byte */
#define TCPIP_THREAD_PRIO 4//0
/*
---------- Sequential layer options ----------
*/
#define LWIP_NETCONN 8
/*
---------- Socket options ----------
*/
#define LWIP_SOCKET 1
#define LWIP_COMPAT_SOCKETS 1
#define LWIP_POSIX_SOCKETS_IO_NAMES 1
#if !defined(FD_SET) && defined(RHINO_CONFIG_VFS_DEV_NODES)
#define LWIP_SOCKET_OFFSET RHINO_CONFIG_VFS_DEV_NODES
#endif
#define LWIP_SO_SNDTIMEO 1
#define LWIP_SO_RCVTIMEO 1
#define SO_REUSE 1
/*
---------- Statistics options ----------
*/
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
/*
---------- Checksum options ----------
*/
/*
---------- IPv6 options ---------------
*/
/*
---------- Hook options ---------------
*/
#ifdef CONFIG_AOS_MESH
#define LWIP_DECLARE_HOOK \
struct netif *lwip_hook_ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest); \
int lwip_hook_mesh_is_mcast_subscribed(const ip6_addr_t *dest);
#define LWIP_HOOK_IP6_ROUTE(src, dest) lwip_hook_ip6_route(src, dest)
#define LWIP_HOOK_MESH_IS_MCAST_SUBSCRIBED(dest) lwip_hook_mesh_is_mcast_subscribed(dest)
#endif
/*
---------- Debugging options ----------
*/
//#define LWIP_DEBUG 1
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL
#define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT)
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_ON
#define API_MSG_DEBUG LWIP_DBG_ON
#define TCPIP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_ON
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_ON
#define TCP_OUTPUT_DEBUG LWIP_DBG_ON
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
/*
---------- Performance tracking options ----------
*/
/*
---------- PPP options ----------
*/
#define PPP_SUPPORT 0
#define LWIP_NETCONN_SEM_PER_THREAD 1
#endif /* LWIP_LWIPOPTS_H */

View file

@ -0,0 +1,23 @@
/**
******************************************************************************
*
* @file system_version.h
*
* @brief lega version info provide
*
* Copyright (C) ASR
*
******************************************************************************
*/
#ifndef __SYSTEM_VERSION_H__
#define __SYSTEM_VERSION_H__
/**
* Get wifi version.
*
* @return wifi version success, 0 failure.
*/
const char *lega_get_wifi_version(void);
#endif //__SYSTEM_VERSION_H__

View file

@ -0,0 +1,165 @@
/*
*****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x08040000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x10000; /* required amount of heap */
_Min_Stack_Size = 0x2000; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH (xr) : ORIGIN = 0x00040000, LENGTH = 1024K
RAM(rw) : ORIGIN = 0x08000000, LENGTH = 256K
SHARED_MEMORY(rw) : ORIGIN = 0x60000000, LENGTH = 128K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = 0xA0;
} >FLASH
.app_version_sec :
{
KEEP(*(app_version_sec))
. = ALIGN(0x10);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
*(seg_flash_driver);
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT>FLASH
/* shared RAM */
SHAREDRAM ORIGIN(SHARED_MEMORY):
{
. = ALIGN(4);
*ipc_shared.o(COMMON)
*hal_desc.o(COMMON)
*txl_buffer_shared.o(COMMON)
*txl_frame_shared.o(COMMON)
*scan_shared.o(COMMON)
*scanu_shared.o(COMMON)
. = ALIGN(4);
} >SHARED_MEMORY AT>FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
/* User_heap_stack section, used to check that there is enough RAM left */
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
/* system stack */
PROVIDE (_stack_base = _estack - _Min_Stack_Size); /* _estack is top of stack*/
ASSERT ((_stack_base > end), "Error: No room left for the stack")
/* _estack is top of stack*/
/* left ram for heap */
PROVIDE (heap_start = _end);
PROVIDE (heap_end = _stack_base);
PROVIDE (heap_len = heap_end - heap_start);
ASSERT ((heap_len > _Min_Heap_Size), "Error: No room left for the heap")
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View file

@ -0,0 +1,163 @@
/*
*****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x08038000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x10000; /* required amount of heap */
_Min_Stack_Size = 0x2000; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH (xr) : ORIGIN = 0x10040000, LENGTH = 768K
RAM(rw) : ORIGIN = 0x08000000, LENGTH = 224K
SHARED_MEMORY(rw) : ORIGIN = 0x60000000, LENGTH = 32K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = 0x100;
} >FLASH
.app_version_sec :
{
KEEP(*(app_version_sec))
. = ALIGN(0x10);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
*(seg_flash_driver);
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT>FLASH
/* shared RAM */
/* shared RAM */
sharemem(NOLOAD):
{
. = ALIGN(4);
_shmem_s = .;
*(SHAREDRAM)
. = ALIGN(4);
_shmem_e = .;
} >SHARED_MEMORY
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
/* User_heap_stack section, used to check that there is enough RAM left */
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
/* system stack */
PROVIDE (_stack_base = _estack - _Min_Stack_Size); /* _estack is top of stack*/
ASSERT ((_stack_base > end), "Error: No room left for the stack")
/* _estack is top of stack*/
/* left ram for heap */
PROVIDE (heap_start = _end);
PROVIDE (heap_end = _stack_base);
PROVIDE (heap_len = heap_end - heap_start);
ASSERT ((heap_len > _Min_Heap_Size), "Error: No room left for the heap")
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View file

@ -0,0 +1,174 @@
#include <stdio.h>
#include "board.h"
#include "lega_cm4.h"
#include "lega_common.h"
#include "systick_delay.h"
#include "lega_uart.h"
#include "lega_wdg.h"
#include "lega_flash.h"
#include "lega_common.h"
#include "lega_wlan_api.h"
#define SYS_APP_VERSION_SEG __attribute__((section("app_version_sec")))
SYS_APP_VERSION_SEG const char app_version[] = SYSINFO_APP_VERSION;
extern hal_wifi_module_t sim_aos_wifi_lega;
extern void NVIC_init();
extern int soc_pre_init(void);
#ifdef ALIOS_SUPPORT
extern void ota_roll_back_pro(void);
#endif
static void wifi_common_init()
{
printf("start------wifi_hal\r\n");
hal_wifi_register_module(&sim_aos_wifi_lega);
hal_wifi_init();
}
/***********************************************************
* init IRQ, set priority and enable IRQ
*
**********************************************************/
void NVIC_init()
{
//set irq priority, default set configLIBRARY_NORMAL_INTERRUPT_PRIORITY
NVIC_SetPriority(UART0_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(UART1_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(UART2_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(CEVA_RW_IP_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(D_APLL_UNLOCK_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(D_SX_UNLOCK_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(SLEEP_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(WDG_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(FLASH_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(GPIO_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(TIMER_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(CRYPTOCELL310_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(DMA_CTRL_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(SPI0_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(SPI1_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(SPI2_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(I2C0_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(I2C1_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(SDIO_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
NVIC_SetPriority(PLF_WAKEUP_IRQn,configLIBRARY_NORMAL_INTERRUPT_PRIORITY);
}
#ifdef ALIOS_SUPPORT
uart_dev_t uart_0;
void hal_uart1_callback_handler(char ch);
#endif
void uart_init(void)
{
#ifdef ALIOS_SUPPORT
//uart_0.port=LEGA_UART1_INDEX;
uart_0.port = PORT_UART_STD; /*logic port*/
#ifdef HIGHFREQ_MCU160_SUPPORT
uart_0.config.baud_rate=UART_BAUDRATE_1000000;
#else
uart_0.config.baud_rate=UART_BAUDRATE_115200;
#endif
uart_0.config.data_width = DATA_8BIT;
uart_0.config.flow_control = FLOW_CTRL_DISABLED;
uart_0.config.parity = PARITY_NO;
uart_0.config.stop_bits = STOP_1BIT;
//uart_0.priv = (void *)(hal_uart1_callback_handler);
hal_uart_init(&uart_0);
#endif
}
#ifdef HIGHFREQ_MCU160_SUPPORT
//all peripheral reinit code should place here
void peripheral_reinit(void)
{
uart_init();
}
#endif
#ifdef SYSTEM_RECOVERY
lega_wdg_dev_t lega_wdg;
void wdg_init(void)
{
lega_wdg.port = 0;
lega_wdg.config.timeout = WDG_TIMEOUT_MS;
lega_wdg_init(&lega_wdg);
}
#endif
/***********************************************************
* init device, such as irq, system clock, uart
**********************************************************/
uint32_t system_bus_clk = SYSTEM_BUS_CLOCK_INIT;
uint32_t system_core_clk = SYSTEM_CORE_CLOCK_INIT;
void lega_devInit()
{
#ifdef _SPI_FLASH_ENABLE_
lega_flash_init();
#endif
#ifdef ALIOS_SUPPORT
ota_roll_back_pro();
#endif
#ifdef SYSTEM_RECOVERY
wdg_init();
#endif
NVIC_init();
#ifdef DCDC_PFMMODE_CLOSE
lega_drv_close_dcdc_pfm();
#endif
lega_drv_rco_cal();
SysTick_Config(SYSTEM_CORE_CLOCK/RHINO_CONFIG_TICKS_PER_SECOND);
//init uart
uart_init();
#ifdef CFG_MIMO_UF
//config to support smartconfig in MIMO scenario
//lega_wlan_smartconfig_mimo_enable();
#endif
#ifdef ALIOS_SUPPORT
hw_start_hal();
#endif
}
/**************************************************
* after task run use board_sys_init to init board
**************************************************/
int board_after_init(void)
{
lega_devInit();
//hw_start_hal();
//NVIC_init();
tcpip_init( NULL, NULL );
wifi_common_init();
//init_uwifi();
return 0;
}
/**************************************************
* before task run use board_sys_init to init board
**************************************************/
void board_init(void)
{
#ifdef LEGA_A0V1
// Clear RFA Only Mode
REG_PMU_CTRL &= ~ENABLE_RFA_DEBUG;
REG_WR(SYS_REG_BASE_FLASH_CLK, 0x01); //26MHz flash,default 13MHz
#endif
flash_partition_init();
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (C) 2015-2019 Alibaba Group Holding Limited
*/
#include "aos/init.h"
#include "board.h"
#include <k_api.h>
#include <stdio.h>
#include <stdlib.h>
#include "lega_cm4.h"
#include "systick_delay.h"
/*
main task stask size(byte)
*/
#define OS_MAIN_TASK_STACK (4096/4)
#define OS_MAIN_TASK_PRI 32
/* For user config
kinit.argc = 0;
kinit.argv = NULL;
kinit.cli_enable = 1;
*/
static kinit_t kinit = {0, NULL, 1};
static ktask_t *g_main_task;
extern void board_init(void);
static void sys_init(void)
{
board_after_init();
/*aos components init including middleware and protocol and so on !*/
aos_kernel_init(&kinit);
}
void HCLK_SW_IRQHandler(void)
{
SYS_CRM_CLR_HCLK_REC = 0x1;
}
void delay_nop(unsigned int dly)
{
volatile unsigned int i;
for(i=dly; i>0; i--)
{
}
}
void ahb_sync_brid_open(void)
{
unsigned int is_using_sync_down = (REG_AHB_BUS_CTRL & (0x1<<1));
if(!is_using_sync_down)
{
REG_AHB_BUS_CTRL |= (0x1<<1); //0x40000A90 bit1 sw_use_hsync
__enable_irq();
NVIC_EnableIRQ(24);
__asm volatile("DSB");
__asm volatile("WFI");
__asm volatile("ISB");
delay_nop(50);
}
}
int main(void)
{
ahb_sync_brid_open();
lega_flash_alg_cache_flush();
board_init();
/*kernel init, malloc can use after this!*/
krhino_init();
/*main task to run */
krhino_task_dyn_create(&g_main_task, "main_task", 0, OS_MAIN_TASK_PRI, 0, OS_MAIN_TASK_STACK, (task_entry_t)sys_init, 1);
/*kernel start schedule!*/
krhino_start();
/*never run here*/
return 0;
}

View file

@ -0,0 +1,244 @@
/************************** startup_cm4.s **********************************************/
.syntax unified
.cpu cortex-m4
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr sp, =_estack /* set stack pointer */
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2], #4
LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call static constructors */
/* bl __libc_init_array */
/* Call the application's entry point.*/
bl main
bx lr
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
* @param None
* @retval None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
*******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
/* External Interrupts */
.word intc_irq /* intc_irq CEVA RW IP Interrupt */
.word SLEEP_IRQHandler /* Sleep Wake-Up Interrupt */
.word WDG_IRQHandler /* Window WatchDog */
.word FLASH_IRQHandler /* FLASH */
.word GPIO_IRQHandler /* GPIO */
.word TIMER_IRQHandler /* Timer interrupt */
.word CRYPTOCELL310_IRQHandler /* CryptoCell 310 Interrupt */
.word DMA_CTRL_IRQHandler /* Generic DMA Ctrl Interrupt */
.word UART0_IRQHandler /* UART0 Interrupt */
.word UART1_IRQHandler /* UART1 Interrupt */
.word UART2_IRQHandler /* UART2 Interrupt */
.word SPI0_IRQHandler /* SPI0 */
.word SPI1_IRQHandler /* SPI1 */
.word SPI2_IRQHandler /* SPI2 */
.word I2C0_IRQHandler /* I2C0 */
.word I2C1_IRQHandler /* I2C1 */
.word SDIO_IRQHandler /* SDIO Combined Interrupt */
.word D_APLL_UNLOCK_IRQHandler /* RF added: D_APLL_UNLOCK */
.word D_SX_UNLOCK_IRQHandler /* RF added: D_SX_UNLOCK */
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word PLATFORM_WAKEUP_IRQHandler /*!< WiFi SOC Wake-Up Interrupt */
.word HCLK_SW_IRQHandler
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak intc_irq
.thumb_set intc_irq,Default_Handler
.weak SLEEP_IRQHandler
.thumb_set SLEEP_IRQHandler,Default_Handler
.weak WDG_IRQHandler
.thumb_set WDG_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak GPIO_IRQHandler
.thumb_set GPIO_IRQHandler,Default_Handler
.weak TIMER_IRQHandler
.thumb_set TIMER_IRQHandler,Default_Handler
.weak CRYPTOCELL310_IRQHandler
.thumb_set CRYPTOCELL310_IRQHandler,Default_Handler
.weak DMA_CTRL_IRQHandler
.thumb_set DMA_CTRL_IRQHandler,Default_Handler
.weak UART0_IRQHandler
.thumb_set UART0_IRQHandler,Default_Handler
.weak UART1_IRQHandler
.thumb_set UART1_IRQHandler,Default_Handler
.weak UART2_IRQHandler
.thumb_set UART2_IRQHandler,Default_Handler
.weak SPI0_IRQHandler
.thumb_set SPI0_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak I2C0_IRQHandler
.thumb_set I2C0_IRQHandler,Default_Handler
.weak I2C1_IRQHandler
.thumb_set I2C1_IRQHandler,Default_Handler
.weak SDIO_IRQHandler
.thumb_set SDIO_IRQHandler,Default_Handler
.weak D_APLL_UNLOCK_IRQHandler
.thumb_set D_APLL_UNLOCK_IRQHandler,Default_Handler
.weak D_SX_UNLOCK_IRQHandler
.thumb_set D_SX_UNLOCK_IRQHandler,Default_Handler
.weak PLATFORM_WAKEUP_IRQHandler
.thumb_set PLATFORM_WAKEUP_IRQHandler,Default_Handler
.weak HCLK_SW_IRQHandler
.thumb_set HCLK_SW_IRQHandler,Default_Handler
/*****************END OF FILE*********************/

View file

@ -0,0 +1 @@
linux_only_targets="living_platform linkkit_gateway smart_outlet smart_outlet_meter smart_led_bulb smart_led_strip"

View file

@ -0,0 +1,11 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _ATCMD_CONFIG_PLATFORM_H_
#define _ATCMD_CONFIG_PLATFORM_H_
// AT uart
#define AT_UART_PORT 1
#endif

View file

@ -0,0 +1,58 @@
NAME := board_b_l475e
JTAG := stlink-v2-1
$(NAME)_TYPE := kernel
MODULE := 1062
HOST_ARCH := Cortex-M4
HOST_MCU_FAMILY := stm32l475
SUPPORT_BINS := no
$(NAME)_SOURCES := board.c osa_flash.c
GLOBAL_INCLUDES += .
GLOBAL_DEFINES += STDIO_UART=0
GLOBAL_DEFINES += RHINO_CONFIG_TICK_TASK=0
GLOBAL_DEFINES += RHINO_CONFIG_WORKQUEUE=1
sal ?= 1
ifeq (1,$(sal))
$(NAME)_COMPONENTS += sal
module ?= wifi.mk3060
else
GLOBAL_DEFINES += CONFIG_NO_TCPIP
endif
CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_B-L475E
CONFIG_SYSINFO_DEVICE_NAME := B-L475E
GLOBAL_CFLAGS += -DSYSINFO_OS_VERSION=\"$(CONFIG_SYSINFO_OS_VERSION)\"
GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\"
GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\"
ifeq ($(COMPILER),armcc)
else ifeq ($(COMPILER),iar)
else
GLOBAL_LDFLAGS += -L $(SOURCE_ROOT)/board/b_l475e
endif
# Global defines
# HSE_VALUE = STM32 crystal frequency = 26MHz (needed to make UART work correctly)
GLOBAL_DEFINES += $$(if $$(NO_CRLF_STDIO_REPLACEMENT),,CRLF_STDIO_REPLACEMENT)
GLOBAL_CFLAGS += -DSTM32L475xx
WIFI_FIRMWARE_SECTOR_START := 2 #0x2000
FILESYSTEM_IMAGE_SECTOR_START := 256 #0x100000
# Extra build target in mico_standard_targets.mk, include bootloader, and copy output file to eclipse debug file (copy_output_for_eclipse)
EXTRA_TARGET_MAKEFILES += $(MAKEFILES_PATH)/aos_standard_targets.mk
#EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_crc_bin.mk
# Define default component testcase for certification
ifneq (, $(findstring yts, $(BUILD_STRING)))
TEST_COMPONENTS += basic rhino yloop api kv
TEST_COMPONENTS += cjson list digest_algorithm hashtable
TEST_COMPONENTS += netmgr wifi_hal
TEST_COMPONENTS += http cloudcoap
endif

View file

@ -0,0 +1,44 @@
#include "hal/soc/soc.h"
#include <aos/kernel.h>
/* Logic partition on flash devices */
hal_logic_partition_t hal_partitions[HAL_PARTITION_MAX];
void board_init(void)
{
hal_partitions[HAL_PARTITION_APPLICATION].partition_owner = HAL_FLASH_EMBEDDED;
hal_partitions[HAL_PARTITION_APPLICATION].partition_description = "Application";
hal_partitions[HAL_PARTITION_APPLICATION].partition_start_addr = 0x08000000;
hal_partitions[HAL_PARTITION_APPLICATION].partition_length = 0x7D000; //500k bytes
hal_partitions[HAL_PARTITION_APPLICATION].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_owner = HAL_FLASH_EMBEDDED;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_description = "PARAMETER1";
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_start_addr = 0x0807D000;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_length = 0x1000; // 4k bytes
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_owner = HAL_FLASH_EMBEDDED;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_description = "PARAMETER2";
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_start_addr = 0x0807E000;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_length = 0x1000; //4k bytes
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN;
hal_partitions[HAL_PARTITION_OTA_TEMP].partition_owner = HAL_FLASH_EMBEDDED;
hal_partitions[HAL_PARTITION_OTA_TEMP].partition_description = "OTA Storage";
hal_partitions[HAL_PARTITION_OTA_TEMP].partition_start_addr = 0x08080000;
hal_partitions[HAL_PARTITION_OTA_TEMP].partition_length = 0x7D000; //500k bytes
hal_partitions[HAL_PARTITION_OTA_TEMP].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN;
hal_partitions[HAL_PARTITION_PARAMETER_3].partition_owner = HAL_FLASH_EMBEDDED;
hal_partitions[HAL_PARTITION_PARAMETER_3].partition_description = "PARAMETER3";
hal_partitions[HAL_PARTITION_PARAMETER_3].partition_start_addr = 0x080FD000;
hal_partitions[HAL_PARTITION_PARAMETER_3].partition_length = 0x1000; //4k bytes
hal_partitions[HAL_PARTITION_PARAMETER_3].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN;
hal_partitions[HAL_PARTITION_PARAMETER_4].partition_owner = HAL_FLASH_EMBEDDED;
hal_partitions[HAL_PARTITION_PARAMETER_4].partition_description = "PARAMETER4";
hal_partitions[HAL_PARTITION_PARAMETER_4].partition_start_addr = 0x080FE000;
hal_partitions[HAL_PARTITION_PARAMETER_4].partition_length = 0x1000; //4k bytes
hal_partitions[HAL_PARTITION_PARAMETER_4].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN;
}

View file

@ -0,0 +1,10 @@
#define HARDWARE_REVISION "V1.0"
#define MODEL "STM32L4"
#ifdef BOOTLOADER
#define STDIO_UART 0
#define STDIO_UART_BUADRATE 115200
#else
#define STDIO_UART 0
#define STDIO_UART_BUADRATE 115200
#endif

View file

@ -0,0 +1,225 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef CONFIG_H
#define CONFIG_H
/* chip level conf */
#ifndef RHINO_CONFIG_LITTLE_ENDIAN
#define RHINO_CONFIG_LITTLE_ENDIAN 1
#endif
#ifndef RHINO_CONFIG_CPU_STACK_DOWN
#define RHINO_CONFIG_CPU_STACK_DOWN 1
#endif
/* kernel feature conf */
#ifndef RHINO_CONFIG_SEM
#define RHINO_CONFIG_SEM 1
#endif
#ifndef RHINO_CONFIG_QUEUE
#define RHINO_CONFIG_QUEUE 1
#endif
#ifndef RHINO_CONFIG_TASK_SEM
#define RHINO_CONFIG_TASK_SEM 1
#endif
#ifndef RHINO_CONFIG_EVENT_FLAG
#define RHINO_CONFIG_EVENT_FLAG 1
#endif
#ifndef RHINO_CONFIG_TIMER
#define RHINO_CONFIG_TIMER 1
#endif
#ifndef RHINO_CONFIG_BUF_QUEUE
#define RHINO_CONFIG_BUF_QUEUE 1
#endif
#ifndef RHINO_CONFIG_MM_BLK
#define RHINO_CONFIG_MM_BLK 1
#endif
#ifndef RHINO_CONFIG_MM_DEBUG
#define RHINO_CONFIG_MM_DEBUG 1
#endif
#ifndef RHINO_CONFIG_MM_TLF
#define RHINO_CONFIG_MM_TLF 1
#endif
#ifndef RHINO_CONFIG_MM_TLF_BLK_SIZE
#define RHINO_CONFIG_MM_TLF_BLK_SIZE 8192
#endif
#define K_MM_STATISTIC 1
#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT
#define RHINO_CONFIG_MM_MAXMSIZEBIT 19
#endif
#ifndef RHINO_CONFIG_GCC_RETADDR
#define RHINO_CONFIG_GCC_RETADDR 1
#endif
#ifndef RHINO_CONFIG_MM_LEAKCHECK
#define RHINO_CONFIG_MM_LEAKCHECK 0
#endif
#ifndef RHINO_CONFIG_RINGBUF_VENDOR
#define RHINO_CONFIG_RINGBUF_VENDOR 0
#endif
#ifndef RHINO_CONFIG_KOBJ_SET
#define RHINO_CONFIG_KOBJ_SET 1
#endif
/* kernel task conf */
#ifndef RHINO_CONFIG_TASK_SUSPEND
#define RHINO_CONFIG_TASK_SUSPEND 1
#endif
#ifndef RHINO_CONFIG_TASK_INFO
#define RHINO_CONFIG_TASK_INFO 1
#endif
#ifndef RHINO_CONFIG_TASK_DEL
#define RHINO_CONFIG_TASK_DEL 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK
#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 1
#endif
#ifndef RHINO_CONFIG_TASK_WAIT_ABORT
#define RHINO_CONFIG_TASK_WAIT_ABORT 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK
#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1
#endif
#ifndef RHINO_CONFIG_SCHED_RR
#define RHINO_CONFIG_SCHED_RR 1
#endif
#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT
#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50
#endif
#ifndef RHINO_CONFIG_PRI_MAX
#define RHINO_CONFIG_PRI_MAX 62
#endif
#ifndef RHINO_CONFIG_USER_PRI_MAX
#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2)
#endif
/* kernel workqueue conf */
#ifndef RHINO_CONFIG_WORKQUEUE
#define RHINO_CONFIG_WORKQUEUE 1
#endif
#ifndef RHINO_CONFIG_WORKQUEUE_STACK_SIZE
#define RHINO_CONFIG_WORKQUEUE_STACK_SIZE 768
#endif
/* kernel mm_region conf */
#ifndef RHINO_CONFIG_MM_REGION_MUTEX
#define RHINO_CONFIG_MM_REGION_MUTEX 0
#endif
/* kernel timer&tick conf */
#ifndef RHINO_CONFIG_HW_COUNT
#define RHINO_CONFIG_HW_COUNT 0
#endif
#ifndef RHINO_CONFIG_TICK_TASK
#define RHINO_CONFIG_TICK_TASK 0
#endif
#if (RHINO_CONFIG_TICK_TASK > 0)
#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE
#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256
#endif
#ifndef RHINO_CONFIG_TICK_TASK_PRI
#define RHINO_CONFIG_TICK_TASK_PRI 1
#endif
#endif
#ifndef RHINO_CONFIG_TICKLESS
#define RHINO_CONFIG_TICKLESS 0
#endif
#ifndef RHINO_CONFIG_TICKS_PER_SECOND
#define RHINO_CONFIG_TICKS_PER_SECOND 100
#endif
/* must be 2^n size!, such as 1, 2, 4, 8, 16,32, etc....... */
#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY
#define RHINO_CONFIG_TICK_HEAD_ARRAY 8
#endif
/*must reserve enough stack size for timer cb will consume*/
#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE
#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 300
#endif
#ifndef RHINO_CONFIG_TIMER_RATE
#define RHINO_CONFIG_TIMER_RATE 1
#endif
#ifndef RHINO_CONFIG_TIMER_TASK_PRI
#define RHINO_CONFIG_TIMER_TASK_PRI 5
#endif
/* kernel intrpt conf */
#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET
#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0
#endif
#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK
#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0
#endif
#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL
#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u
#endif
#ifndef RHINO_CONFIG_INTRPT_GUARD
#define RHINO_CONFIG_INTRPT_GUARD 0
#endif
/* kernel dyn alloc conf */
#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC
#define RHINO_CONFIG_KOBJ_DYN_ALLOC 1
#endif
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG
#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30
#endif
#ifndef RHINO_CONFIG_K_DYN_TASK_STACK
#define RHINO_CONFIG_K_DYN_TASK_STACK 256
#endif
#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI
#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 6
#endif
#endif
/* kernel idle conf */
#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE
#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200
#endif
/* kernel hook conf */
#ifndef RHINO_CONFIG_USER_HOOK
#define RHINO_CONFIG_USER_HOOK 0
#endif
/* kernel stats conf */
#ifndef RHINO_CONFIG_SYSTEM_STATS
#define RHINO_CONFIG_SYSTEM_STATS 1
#endif
#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS
#define RHINO_CONFIG_DISABLE_SCHED_STATS 0
#endif
#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS
#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_STATS
#define RHINO_CONFIG_CPU_USAGE_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI
#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2)
#endif
#ifndef RHINO_CONFIG_TASK_SCHED_STATS
#define RHINO_CONFIG_TASK_SCHED_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK
#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256
#endif
#ifndef RHINO_CONFIG_CPU_NUM
#define RHINO_CONFIG_CPU_NUM 1
#endif
/* kernel trace conf */
#ifndef RHINO_CONFIG_TRACE
#define RHINO_CONFIG_TRACE 0
#endif
#endif /* CONFIG_H */

View file

@ -0,0 +1,493 @@
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "stm32l4xx_hal.h"
#include "stm32l4xx_hal_flash.h"
#define EN_DBG 0
#define KM_FLASH_ADDR_START 0x080FF000
#define KM_FLASH_ADDR_SIZE 0x1000
#define FLASH_BLOCK_LEN FLASH_PAGE_SIZE
/**
* @brief Gets the page of a given address
* @param Addr: Address of the FLASH Memory
* @retval The page of a given address
*/
static uint32_t GetPage(uint32_t Addr)
{
uint32_t page = 0;
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE))
{
/* Bank 1 */
page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
}
else
{
/* Bank 2 */
page = (Addr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE;
}
return page;
}
/**
* @brief Gets the bank of a given address
* @param Addr: Address of the FLASH Memory
* @retval The bank of a given address
*/
static uint32_t GetBank(uint32_t Addr)
{
uint32_t bank = 0;
if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0)
{
/* No Bank swap */
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE))
{
bank = FLASH_BANK_1;
}
else
{
bank = FLASH_BANK_2;
}
}
else
{
/* Bank swap */
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE))
{
bank = FLASH_BANK_2;
}
else
{
bank = FLASH_BANK_1;
}
}
return bank;
}
int32_t osa_flash_read(void *addr, void *out, size_t size)
{
#if EN_DBG
printf("flash read addr 0x%08x size 0x%08x\n", (uint32_t)addr, size);
#endif
memcpy(out, addr ,size);
#if EN_DBG
printf("data 0x%02x 0x%02x 0x%02x 0x%02x\n",
*((uint8_t *)out + 0), *((uint8_t *)out + 1),
*((uint8_t *)out + 2), *((uint8_t *)out + 3));
#endif
return 0;
}
int32_t osa_flash_write(void *addr, void *buf, size_t size)
{
uint64_t *p = (uint64_t *)buf;
uint32_t a = (uint32_t)addr;
HAL_StatusTypeDef ret = HAL_OK;
if (0 != ((uint32_t)addr % 8) || 0 != (size % 8)) {
printf("bad param addr 0x%08x size 0x%08x\n",
(unsigned int)addr , (unsigned int)size);
return -1;
}
#if EN_DBG
printf("flash write addr 0x%08x size 0x%08x\n",
(uint32_t)addr , (uint32_t)size);
#endif
HAL_FLASH_Unlock();
while ((size >= 8) && (ret == HAL_OK)) {
ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)a, (uint64_t)(*p));
if (0 != ret) {
printf("write flash fail addr %08x data %llx ret 0x%08x\n",
(unsigned int)a, (uint64_t)(*p), (unsigned int)ret);
return -1;
}
#if EN_DBG
uint8_t tmp_buf[8];
int i;
osa_flash_read((void *)a , tmp_buf, 8);
if (0 != memcmp(tmp_buf, p, 8)) {
printf("write than read not match \n");
for (i = 0; i < 8; ++i) {
printf("write buf 0x%02x read data 0x%02x\n", *((uint8_t *)p + i), tmp_buf[i]);
}
return -1;
}
#if 0
for (i = 0; i < 8; ++i) {
printf("write buf 0x%02x read data 0x%02x\n", *((uint8_t *)p + i), tmp_buf[i]);
}
#endif
#endif
p = (uint64_t *)((uint32_t)p + 8);
a += 8;
size -= 8;
}
HAL_FLASH_Lock();
return 0;
}
int32_t osa_flash_erase(void *addr, size_t size)
{
uint32_t PageError = 0;
FLASH_EraseInitTypeDef pEraseInit;
uint32_t cur_addr = (uint32_t)addr;
size_t cur_size = size;
HAL_FLASH_Unlock();
if (0 != (size % FLASH_BLOCK_LEN) || 0 != (cur_addr % FLASH_BLOCK_LEN)) {
printf("bad param addr 0x%08x size 0x%08x\n",
(unsigned int)addr, (unsigned int)size);
return -1;
}
if (0 == size) {
return 0;
}
while (cur_size > 0) {
/* Fill EraseInit structure*/
pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
pEraseInit.Banks = GetBank(cur_addr);
pEraseInit.Page = GetPage(cur_addr);
pEraseInit.NbPages = 1;
#if EN_DBG
printf("flash erase page %d bank %d\n", GetPage(cur_addr), GetBank(cur_addr));
#endif
if (HAL_FLASHEx_Erase(&pEraseInit, &PageError) != HAL_OK)
{
printf("flash erase fail\n");
return -1;
}
cur_size -= FLASH_BLOCK_LEN;
cur_addr -= FLASH_BLOCK_LEN;
}
HAL_FLASH_Lock();
return 0;
}
int32_t getRDPLevel(uint32_t *RDPLevel)
{
FLASH_OBProgramInitTypeDef sFlashOptionBytes;
int32_t eRetStatus = 0;
if (NULL == RDPLevel) {
return -1;
}
/* Unlock the Flash to enable the flash control register access
*************/
HAL_FLASH_Unlock();
/* Clear OPTVERR bit set on virgin samples */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
/* Unlock the Options Bytes
*************************************************/
HAL_FLASH_OB_Unlock();
/* Get Option Bytes status for FLASH_BANK_1: WRP AREA_A and PCRoP
**********/
HAL_FLASHEx_OBGetConfig(&sFlashOptionBytes);
*RDPLevel = sFlashOptionBytes.RDPLevel;
/* Lock the Options Bytes
***************************************************/
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
return eRetStatus;
}
int32_t ConfigWRP (bool enable, bool reboot)
{
int32_t eRetStatus = 0;
uint32_t RDPlevel;
uint32_t StartPage = 0, EndPage = 0, StartBank = 0, EndBank = 0;
FLASH_OBProgramInitTypeDef psFlashOptionBytes, psFlashOptionBytes2;
eRetStatus = getRDPLevel(&RDPlevel);
if (0 != eRetStatus) {
return -1;
}
if (OB_RDP_LEVEL_2 == RDPlevel) {
return -1;
}
/* Get the number of the start and end pages */
StartPage = GetPage(KM_FLASH_ADDR_START);
EndPage = GetPage(KM_FLASH_ADDR_START + KM_FLASH_ADDR_SIZE - 1);
/* Get the bank of the start and end pages */
StartBank = GetBank(KM_FLASH_ADDR_START);
EndBank = GetBank(KM_FLASH_ADDR_START + KM_FLASH_ADDR_SIZE - 1);
if (StartBank != EndBank) {
/* cross bank not support now */
return -1;
}
/* WRP area is only on one bank */
if (StartBank == FLASH_BANK_1)
{
psFlashOptionBytes.WRPArea = OB_WRPAREA_BANK1_AREAA;
psFlashOptionBytes2.WRPArea = OB_WRPAREA_BANK1_AREAB;
}
else
{
psFlashOptionBytes.WRPArea = OB_WRPAREA_BANK2_AREAA;
psFlashOptionBytes2.WRPArea = OB_WRPAREA_BANK2_AREAB;
}
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
HAL_FLASH_OB_Unlock();
HAL_FLASHEx_OBGetConfig(&psFlashOptionBytes);
HAL_FLASHEx_OBGetConfig(&psFlashOptionBytes2);
if (true == enable) {
/* Check if desired pages are not yet write protected ***********************/
if ((psFlashOptionBytes.WRPStartOffset <= StartPage) && (psFlashOptionBytes.WRPEndOffset >= (StartPage - 1)))
{
/* Current area is adjacent to pages to be write protected */
if (psFlashOptionBytes.WRPEndOffset < EndPage)
{
/* Current area will be extended to include the pages to be write protected */
psFlashOptionBytes.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes.WRPEndOffset = EndPage;
}
}
else if ((psFlashOptionBytes.WRPStartOffset <= (EndPage + 1)) && (psFlashOptionBytes.WRPEndOffset >= EndPage))
{
/* Current area is adjacent to pages to be write protected */
if (psFlashOptionBytes.WRPStartOffset > StartPage)
{
/* Current area will be extended to include the pages to be write protected */
psFlashOptionBytes.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes.WRPStartOffset = StartPage;
}
}
else if ((psFlashOptionBytes.WRPStartOffset > StartPage) && (psFlashOptionBytes.WRPEndOffset < EndPage))
{
/* Current area is included in pages to be write protected */
psFlashOptionBytes.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes.WRPStartOffset = StartPage;
psFlashOptionBytes.WRPEndOffset = EndPage;
}
else if ((psFlashOptionBytes2.WRPStartOffset <= StartPage) && (psFlashOptionBytes2.WRPEndOffset >= (StartPage - 1)))
{
/* Current area is adjacent to pages to be write protected */
if (psFlashOptionBytes2.WRPEndOffset < EndPage)
{
/* Current area will be extended to include the pages to be write protected */
psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes2.WRPEndOffset = EndPage;
}
}
else if ((psFlashOptionBytes2.WRPStartOffset <= (EndPage + 1)) && (psFlashOptionBytes2.WRPEndOffset >= EndPage))
{
/* Current area is adjacent to pages to be write protected */
if (psFlashOptionBytes2.WRPStartOffset > StartPage)
{
/* Current area will be extended to include the pages to be write protected */
psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes2.WRPStartOffset = StartPage;
}
}
else if ((psFlashOptionBytes2.WRPStartOffset > StartPage) && (psFlashOptionBytes2.WRPEndOffset < EndPage))
{
/* Current area is included in pages to be write protected */
psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes2.WRPStartOffset = StartPage;
psFlashOptionBytes2.WRPEndOffset = EndPage;
}
else if (psFlashOptionBytes.WRPStartOffset > psFlashOptionBytes.WRPEndOffset)
{
/* Current area is not used => it will be configured to protect the pages */
psFlashOptionBytes.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes.WRPStartOffset = StartPage;
psFlashOptionBytes.WRPEndOffset = EndPage;
}
else if (psFlashOptionBytes2.WRPStartOffset > psFlashOptionBytes2.WRPEndOffset)
{
/* Current area is not used => it will be configured to protect the pages */
psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes2.WRPStartOffset = StartPage;
psFlashOptionBytes2.WRPEndOffset = EndPage;
}
else
{
/* No more area available to protect the pages */
/* => Error : not possible to activate the pages indicated */
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
eRetStatus = -1;
}
} else {
/* disable */
/* Check if desired pages are already write protected ***********************/
if ((psFlashOptionBytes.WRPStartOffset == StartPage) && (psFlashOptionBytes.WRPEndOffset == EndPage))
{
/* Current area correspond to the area to disable */
psFlashOptionBytes.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes.WRPStartOffset = 0xFF;
psFlashOptionBytes.WRPEndOffset = 0;
}
else if ((psFlashOptionBytes.WRPStartOffset == StartPage) && (psFlashOptionBytes.WRPEndOffset > EndPage))
{
/* Current area is bigger than the area to disable : */
/* - End of area is bigger than the last page to un-protect */
psFlashOptionBytes.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes.WRPStartOffset = EndPage + 1;
}
else if ((psFlashOptionBytes.WRPStartOffset < StartPage) && (psFlashOptionBytes.WRPEndOffset == EndPage))
{
/* Current area is bigger than the area to disable : */
/* - Start of area is lower than the first page to un-protect */
psFlashOptionBytes.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes.WRPEndOffset = StartPage - 1;
}
else if ((psFlashOptionBytes.WRPStartOffset < StartPage) && (psFlashOptionBytes.WRPEndOffset > EndPage))
{
/* Current area is bigger than the area to disable */
/* - Start of area is lower than the first page to un-protect */
/* - End of area is bigger than the last page to un-protect */
if (psFlashOptionBytes2.WRPStartOffset > psFlashOptionBytes2.WRPEndOffset)
{
/* Second area of the bank can be used */
psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes2.WRPStartOffset = EndPage + 1;
psFlashOptionBytes2.WRPEndOffset = psFlashOptionBytes.WRPEndOffset;
psFlashOptionBytes.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes.WRPEndOffset = StartPage - 1;
}
else
{
/* Second area of the bank already used for WRP */
/* => Error : not possible to deactivate only the pages indicated */
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
eRetStatus = -1;
}
}
else if ((psFlashOptionBytes2.WRPStartOffset == StartPage) && (psFlashOptionBytes2.WRPEndOffset == EndPage))
{
/* Current area correspond to the area to disable */
psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes2.WRPStartOffset = 0xFF;
psFlashOptionBytes2.WRPEndOffset = 0;
}
else if ((psFlashOptionBytes2.WRPStartOffset == StartPage) && (psFlashOptionBytes2.WRPEndOffset > EndPage))
{
/* Current area is bigger than the area to disable : */
/* - End of area is bigger than the last page to un-protect */
psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes2.WRPStartOffset = EndPage + 1;
}
else if ((psFlashOptionBytes2.WRPStartOffset < StartPage) && (psFlashOptionBytes2.WRPEndOffset == EndPage))
{
/* Current area is bigger than the area to disable : */
/* - Start of area is lower than the first page to un-protect */
psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes2.WRPEndOffset = StartPage - 1;
}
else if ((psFlashOptionBytes2.WRPStartOffset < StartPage) && (psFlashOptionBytes2.WRPEndOffset > EndPage))
{
/* Current area is bigger than the area to disable */
/* - Start of area is lower than the first page to un-protect */
/* - End of area is bigger than the last page to un-protect */
if (psFlashOptionBytes.WRPStartOffset > psFlashOptionBytes.WRPEndOffset)
{
/* Second area of the bank can be used */
psFlashOptionBytes.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes.WRPStartOffset = EndPage + 1;
psFlashOptionBytes.WRPEndOffset = psFlashOptionBytes2.WRPEndOffset;
psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes2.WRPEndOffset = StartPage - 1;
}
else
{
/* Second area of the bank already used for WRP */
/* => Error : not possible to deactivate only the pages indicated */
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
eRetStatus = -1;
}
}
}
/* Configure write protected pages */
if (psFlashOptionBytes.OptionType == OPTIONBYTE_WRP)
{
if(HAL_FLASHEx_OBProgram(&psFlashOptionBytes) != HAL_OK)
{
/* Error occurred while options bytes programming. **********************/
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
eRetStatus = -1;
}
}
if (psFlashOptionBytes2.OptionType == OPTIONBYTE_WRP)
{
if(HAL_FLASHEx_OBProgram(&psFlashOptionBytes2) != HAL_OK)
{
/* Error occurred while options bytes programming. **********************/
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
eRetStatus = -1;
}
}
/* Generate System Reset to load the new option byte values ***************/
if (((psFlashOptionBytes.OptionType == OPTIONBYTE_WRP) || (psFlashOptionBytes2.OptionType == OPTIONBYTE_WRP)) && reboot)
{
HAL_FLASH_OB_Launch();
}
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
return eRetStatus;
}
int32_t CleanProtectionWRP (void)
{
int32_t eRetStatus = 0;
uint32_t RDPlevel;
FLASH_OBProgramInitTypeDef psFlashOptionBytes;
eRetStatus = getRDPLevel(&RDPlevel);
if (0 != eRetStatus) {
return -1;
}
if (OB_RDP_LEVEL_2 == RDPlevel) {
return -1;
}
psFlashOptionBytes.OptionType = OPTIONBYTE_WRP;
psFlashOptionBytes.WRPArea = 0;//SFU_HAL_IF_PROTECT_WRP_AREA_1;
psFlashOptionBytes.WRPStartOffset = 0;
psFlashOptionBytes.WRPEndOffset = 0;
if (HAL_FLASHEx_OBProgram(&psFlashOptionBytes) != HAL_OK) {
eRetStatus = -1;
}
return eRetStatus;
}

View file

@ -0,0 +1,35 @@
/*
* Script for GNU linker.
* Describes layout of sections, location of stack.
*
* In this case vectors are at location 0 (reset @ 0x08)
*
* +------------+ 0x00400000
* data |
* end
* |(heap) |
* . .
* . .
* |(heap limit)|
*
* |- - - - - - |
* stack bottom 256k
* +------------+
*
* +------------+ 0x0000000
* |vectors |
* | |
* |------------+
* |text |
* |data |
* | | 1024k
* +------------+
*/
/* Split memory into area for vectors and ram */
MEMORY
{
flash (rx) : ORIGIN = 0x00000000, LENGTH = 2M
ram (rwx): ORIGIN = 0x00400020, LENGTH = 256k - 32
}

View file

@ -0,0 +1,29 @@
NAME := board_bk7231
JTAG := jlink
$(NAME)_TYPE := kernel
MODULE := BK7231
HOST_ARCH := ARM968E-S
HOST_MCU_FAMILY := bk7231
SUPPORT_BINS := no
$(NAME)_SOURCES := board.c
GLOBAL_INCLUDES += .
GLOBAL_DEFINES += STDIO_UART=1
CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_BK7231
CONFIG_SYSINFO_DEVICE_NAME := BK7231
GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\"
GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\"
#GLOBAL_CFLAGS += -DSYSINFO_KERNEL_VERSION=\"$(CONFIG_SYSINFO_KERNEL_VERSION)\"
#GLOBAL_CFLAGS += -DSYSINFO_APP_VERSION=\"$(CONFIG_SYSINFO_APP_VERSION)\"
GLOBAL_LDS_INCLUDES += $(SOURCE_ROOT)/board/bk7231devkitc/bk7231devkitc.ld.S
# Extra build target in aos_standard_targets.mk, include bootloader, and copy output file to eclipse debug file (copy_output_for_eclipse)
EXTRA_TARGET_MAKEFILES += $(MAKEFILES_PATH)/aos_standard_targets.mk
EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_crc_bin.mk

View file

@ -0,0 +1,186 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "hal/soc/soc.h"
#include <aos/kernel.h>
#include <aos/aos.h>
/* Logic partition on flash devices */
const hal_logic_partition_t hal_partitions[] =
{
[HAL_PARTITION_BOOTLOADER] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "Bootloader",
.partition_start_addr = 0x00000,
.partition_length = 0x10000, //64k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_APPLICATION] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "Application",
.partition_start_addr = 0x00000,//phy is 0x11000
.partition_length = 0xAF000, //700k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_1] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER1",
.partition_start_addr = 0x100000,
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_2] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER2",
.partition_start_addr = 0x101000,
.partition_length = 0x2000, // 8k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_OTA_TEMP] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "OTA Storage",
.partition_start_addr = 0x103000,
.partition_length = 0xAF000, //700k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_3] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER3",
.partition_start_addr = 0x1B2000,
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_4] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER4",
.partition_start_addr = 0x1B3000,
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_RF_FIRMWARE] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "RF parameter",
.partition_start_addr = 0x1B4000,// rf parameter is 0x1A2000
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
};
#define KEY_BOOT 15
#define KEY_PS 14
static uint64_t elink_time = 0;
static uint64_t ps_time = 0;
static gpio_dev_t gpio_key_boot;
static gpio_dev_t gpio_key_ps;
static void key_poll_func(void *arg)
{
uint32_t level;
uint64_t diff;
hal_gpio_input_get(&gpio_key_boot, &level);
if (level == 0) {
aos_post_delayed_action(10, key_poll_func, NULL);
} else {
diff = aos_now_ms() - elink_time;
if (diff > 2000) { /* long press */
elink_time = 0;
aos_post_event(EV_KEY, CODE_BOOT, VALUE_KEY_LTCLICK);
} else if (diff > 40) { /* short press */
elink_time = 0;
aos_post_event(EV_KEY, CODE_BOOT, VALUE_KEY_CLICK);
} else {
aos_post_delayed_action(10, key_poll_func, NULL);
}
}
}
static void key_ps_func(void *arg)
{
#if 0
uint32_t level;
uint64_t diff;
hal_gpio_input_get(&gpio_key_ps, &level);
if (level == 0) {
aos_post_delayed_action(10, key_ps_func, NULL);
} else {
diff = aos_now_ms() - ps_time;
if (diff > 40) {
ps_time = 0;
aos_post_event(EV_KEY, CODE_BOOT, VALUE_KEY_PSCLICK);
}else if (diff > 2000) { /* short press */
elink_time = 0;
aos_post_event(EV_KEY, CODE_BOOT, VALUE_KEY_LPSCLICK);
} else {
aos_post_delayed_action(10, key_ps_func, NULL);
}
}
#endif
}
static void key_proc_work(void *arg)
{
aos_schedule_call(key_poll_func, NULL);
}
static void key_ps_work(void *arg)
{
aos_schedule_call(key_ps_func, NULL);
}
static void handle_elink_key(void *arg)
{
uint32_t gpio_value;
hal_gpio_input_get(&gpio_key_boot, &gpio_value);
if (gpio_value == 0 && elink_time == 0) {
elink_time = aos_now_ms();
aos_loop_schedule_work(0, key_proc_work, NULL, NULL, NULL);
}
}
static void handle_ps_key(void *arg)
{
uint32_t gpio_value;
hal_gpio_input_get(&gpio_key_ps, &gpio_value);
if (gpio_value == 0 && ps_time == 0) {
ps_time = aos_now_ms();
aos_loop_schedule_work(0, key_ps_work, NULL, NULL, NULL);
}
}
void board_init(void)
{
gpio_key_boot.port = KEY_BOOT;
gpio_key_boot.config = INPUT_PULL_UP;
hal_gpio_init(&gpio_key_boot);
hal_gpio_clear_irq(&gpio_key_boot);
hal_gpio_enable_irq(&gpio_key_boot, IRQ_TRIGGER_FALLING_EDGE, handle_elink_key, NULL);
gpio_key_ps.port = KEY_PS;
gpio_key_ps.config = INPUT_PULL_UP;
hal_gpio_init(&gpio_key_ps);
hal_gpio_clear_irq(&gpio_key_ps);
hal_gpio_enable_irq(&gpio_key_ps, IRQ_TRIGGER_FALLING_EDGE, handle_ps_key, NULL);
}
int board_cli_init(void)
{
}

View file

@ -0,0 +1,14 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#define HARDWARE_REVISION "V1.0"
#define MODEL "BK7231"
#ifdef BOOTLOADER
#define STDIO_UART 1
#define STDIO_UART_BUADRATE 115200
#else
#define STDIO_UART 1
#define STDIO_UART_BUADRATE 115200
#endif

View file

@ -0,0 +1,225 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef CONFIG_H
#define CONFIG_H
/* chip level conf */
#ifndef RHINO_CONFIG_LITTLE_ENDIAN
#define RHINO_CONFIG_LITTLE_ENDIAN 1
#endif
#ifndef RHINO_CONFIG_CPU_STACK_DOWN
#define RHINO_CONFIG_CPU_STACK_DOWN 1
#endif
/* kernel feature conf */
#ifndef RHINO_CONFIG_SEM
#define RHINO_CONFIG_SEM 1
#endif
#ifndef RHINO_CONFIG_QUEUE
#define RHINO_CONFIG_QUEUE 1
#endif
#ifndef RHINO_CONFIG_TASK_SEM
#define RHINO_CONFIG_TASK_SEM 1
#endif
#ifndef RHINO_CONFIG_EVENT_FLAG
#define RHINO_CONFIG_EVENT_FLAG 1
#endif
#ifndef RHINO_CONFIG_TIMER
#define RHINO_CONFIG_TIMER 1
#endif
#ifndef RHINO_CONFIG_BUF_QUEUE
#define RHINO_CONFIG_BUF_QUEUE 1
#endif
#ifndef RHINO_CONFIG_MM_BLK
#define RHINO_CONFIG_MM_BLK 1
#endif
#ifndef RHINO_CONFIG_MM_DEBUG
#define RHINO_CONFIG_MM_DEBUG 1
#endif
#ifndef RHINO_CONFIG_MM_TLF
#define RHINO_CONFIG_MM_TLF 1
#endif
#ifndef RHINO_CONFIG_MM_TLF_BLK_SIZE
#define RHINO_CONFIG_MM_TLF_BLK_SIZE 8192
#endif
#define K_MM_STATISTIC 1
#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT
#define RHINO_CONFIG_MM_MAXMSIZEBIT 19
#endif
#ifndef RHINO_CONFIG_GCC_RETADDR
#define RHINO_CONFIG_GCC_RETADDR 1
#endif
#ifndef RHINO_CONFIG_MM_LEAKCHECK
#define RHINO_CONFIG_MM_LEAKCHECK 1
#endif
#ifndef RHINO_CONFIG_RINGBUF_VENDOR
#define RHINO_CONFIG_RINGBUF_VENDOR 0
#endif
#ifndef RHINO_CONFIG_KOBJ_SET
#define RHINO_CONFIG_KOBJ_SET 1
#endif
/* kernel task conf */
#ifndef RHINO_CONFIG_TASK_SUSPEND
#define RHINO_CONFIG_TASK_SUSPEND 1
#endif
#ifndef RHINO_CONFIG_TASK_INFO
#define RHINO_CONFIG_TASK_INFO 1
#endif
#ifndef RHINO_CONFIG_TASK_DEL
#define RHINO_CONFIG_TASK_DEL 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK
#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 1
#endif
#ifndef RHINO_CONFIG_TASK_WAIT_ABORT
#define RHINO_CONFIG_TASK_WAIT_ABORT 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK
#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1
#endif
#ifndef RHINO_CONFIG_SCHED_RR
#define RHINO_CONFIG_SCHED_RR 1
#endif
#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT
#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50
#endif
#ifndef RHINO_CONFIG_PRI_MAX
#define RHINO_CONFIG_PRI_MAX 62
#endif
#ifndef RHINO_CONFIG_USER_PRI_MAX
#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2)
#endif
/* kernel workqueue conf */
#ifndef RHINO_CONFIG_WORKQUEUE
#define RHINO_CONFIG_WORKQUEUE 1
#endif
#ifndef RHINO_CONFIG_WORKQUEUE_STACK_SIZE
#define RHINO_CONFIG_WORKQUEUE_STACK_SIZE 768
#endif
/* kernel mm_region conf */
#ifndef RHINO_CONFIG_MM_REGION_MUTEX
#define RHINO_CONFIG_MM_REGION_MUTEX 0
#endif
/* kernel timer&tick conf */
#ifndef RHINO_CONFIG_HW_COUNT
#define RHINO_CONFIG_HW_COUNT 0
#endif
#ifndef RHINO_CONFIG_TICK_TASK
#define RHINO_CONFIG_TICK_TASK 0
#endif
#if (RHINO_CONFIG_TICK_TASK > 0)
#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE
#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256
#endif
#ifndef RHINO_CONFIG_TICK_TASK_PRI
#define RHINO_CONFIG_TICK_TASK_PRI 1
#endif
#endif
#ifndef RHINO_CONFIG_TICKLESS
#define RHINO_CONFIG_TICKLESS 0
#endif
#ifndef RHINO_CONFIG_TICKS_PER_SECOND
#define RHINO_CONFIG_TICKS_PER_SECOND 500
#endif
/* must be 2^n size!, such as 1, 2, 4, 8, 16,32, etc....... */
#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY
#define RHINO_CONFIG_TICK_HEAD_ARRAY 8
#endif
/*must reserve enough stack size for timer cb will consume*/
#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE
#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 300
#endif
#ifndef RHINO_CONFIG_TIMER_RATE
#define RHINO_CONFIG_TIMER_RATE 1
#endif
#ifndef RHINO_CONFIG_TIMER_TASK_PRI
#define RHINO_CONFIG_TIMER_TASK_PRI 5
#endif
/* kernel intrpt conf */
#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET
#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0
#endif
#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK
#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0
#endif
#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL
#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u
#endif
#ifndef RHINO_CONFIG_INTRPT_GUARD
#define RHINO_CONFIG_INTRPT_GUARD 0
#endif
/* kernel dyn alloc conf */
#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC
#define RHINO_CONFIG_KOBJ_DYN_ALLOC 1
#endif
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG
#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30
#endif
#ifndef RHINO_CONFIG_K_DYN_TASK_STACK
#define RHINO_CONFIG_K_DYN_TASK_STACK 256
#endif
#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI
#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 6
#endif
#endif
/* kernel idle conf */
#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE
#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200
#endif
/* kernel hook conf */
#ifndef RHINO_CONFIG_USER_HOOK
#define RHINO_CONFIG_USER_HOOK 0
#endif
/* kernel stats conf */
#ifndef RHINO_CONFIG_SYSTEM_STATS
#define RHINO_CONFIG_SYSTEM_STATS 1
#endif
#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS
#define RHINO_CONFIG_DISABLE_SCHED_STATS 0
#endif
#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS
#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_STATS
#define RHINO_CONFIG_CPU_USAGE_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI
#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2)
#endif
#ifndef RHINO_CONFIG_TASK_SCHED_STATS
#define RHINO_CONFIG_TASK_SCHED_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK
#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256
#endif
#ifndef RHINO_CONFIG_CPU_NUM
#define RHINO_CONFIG_CPU_NUM 1
#endif
/* kernel trace conf */
#ifndef RHINO_CONFIG_TRACE
#define RHINO_CONFIG_TRACE 0
#endif
#endif /* CONFIG_H */

View file

@ -0,0 +1,13 @@
## Overview
## Feature of Board
## Directories
```sh
bk7231sdevkitc # configuration files for board bk7231sdevkitc
```
## Board Hardware Resources
## Update log

View file

@ -0,0 +1,35 @@
/*
* Script for GNU linker.
* Describes layout of sections, location of stack.
*
* In this case vectors are at location 0 (reset @ 0x08)
*
* +------------+ 0x00400000
* data |
* end
* |(heap) |
* . .
* . .
* |(heap limit)|
*
* |- - - - - - |
* stack bottom 256k
* +------------+
*
* +------------+ 0x0000000
* |vectors |
* | |
* |------------+
* |text |
* |data |
* | | 1024k
* +------------+
*/
/* Split memory into area for vectors and ram */
MEMORY
{
flash (rx) : ORIGIN = 0x00010000, LENGTH = 2M - 64k
ram (rwx): ORIGIN = 0x00400020, LENGTH = 256k - 32
}

View file

@ -0,0 +1,40 @@
NAME := board_bk7231s
JTAG := jlink
$(NAME)_MBINS_TYPE := kernel
$(NAME)_VERSION := 1.0.0
$(NAME)_SUMMARY := configuration for board bk7231s
MODULE := BK7231S
HOST_ARCH := ARM968E-S
HOST_MCU_FAMILY := bk7231s
SUPPORT_MBINS := no
$(NAME)_SOURCES := board.c
GLOBAL_INCLUDES += .
GLOBAL_DEFINES += CLI_CONFIG_SUPPORT_BOARD_CMD=1
CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_BK7231S
CONFIG_SYSINFO_DEVICE_NAME := BK7231S
GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\"
GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\"
GLOBAL_LDS_INCLUDES += $(SOURCE_ROOT)/board/bk7231sdevkitc/bk7231sdevkitc.ld
# Extra build target include bootloader, and copy output file to eclipse debug file (copy_output_for_eclipse)
ifeq ($(PING_PONG_OTA),1)
EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_pingpong_bin.mk
else
EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_crc_bin.mk
endif
# Define default component testcase for certification
ifneq (, $(findstring yts, $(BUILD_STRING)))
TEST_COMPONENTS += basic rhino yloop api kv vfs
TEST_COMPONENTS += cjson list digest_algorithm hashtable
TEST_COMPONENTS += netmgr wifi_hal
TEST_COMPONENTS += http cloudcoap
endif

View file

@ -0,0 +1,79 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "hal/soc/soc.h"
#include <aos/kernel.h>
#include <aos/aos.h>
/* Logic partition on flash devices */
const hal_logic_partition_t hal_partitions[] =
{
[HAL_PARTITION_BOOTLOADER] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "Bootloader",
.partition_start_addr = 0x000000,
.partition_length = 0x10000, //64k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_1] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER1",
.partition_start_addr = 0x010000,// boot information need protect
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_APPLICATION] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "Application",
.partition_start_addr = 0x011000,//cpu is 0x10000
.partition_length = 0xE1000, //900k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
/*reserved 52k*/
[HAL_PARTITION_OTA_TEMP] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "OTA Storage",
.partition_start_addr = 0x0FF000,//cpu is 0xF0000
.partition_length = 0xE1000, //900k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
/*protected flash size is 0~1984k. below are not protected.*/
[HAL_PARTITION_PARAMETER_2] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER2",
.partition_start_addr = 0x1F0000,
.partition_length = 0x2000, // 8k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_4] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER4",
.partition_start_addr = 0x1F2000,
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_RF_FIRMWARE] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "RF parameter",
.partition_start_addr = 0x1F3000,
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
};
void board_init(void)
{
}
int board_cli_init(void)
{
}

View file

@ -0,0 +1,13 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#define HARDWARE_REVISION "V1.0"
#define MODEL "BK7231S"
#define STDIO_UART 1
#define STDIO_UART_BUADRATE 115200
#define BK_UART 0
#define BK_UART_BUADRATE 115200

View file

@ -0,0 +1,225 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef CONFIG_H
#define CONFIG_H
/* chip level conf */
#ifndef RHINO_CONFIG_LITTLE_ENDIAN
#define RHINO_CONFIG_LITTLE_ENDIAN 1
#endif
#ifndef RHINO_CONFIG_CPU_STACK_DOWN
#define RHINO_CONFIG_CPU_STACK_DOWN 1
#endif
/* kernel feature conf */
#ifndef RHINO_CONFIG_SEM
#define RHINO_CONFIG_SEM 1
#endif
#ifndef RHINO_CONFIG_QUEUE
#define RHINO_CONFIG_QUEUE 1
#endif
#ifndef RHINO_CONFIG_TASK_SEM
#define RHINO_CONFIG_TASK_SEM 1
#endif
#ifndef RHINO_CONFIG_EVENT_FLAG
#define RHINO_CONFIG_EVENT_FLAG 1
#endif
#ifndef RHINO_CONFIG_TIMER
#define RHINO_CONFIG_TIMER 1
#endif
#ifndef RHINO_CONFIG_BUF_QUEUE
#define RHINO_CONFIG_BUF_QUEUE 1
#endif
#ifndef RHINO_CONFIG_MM_BLK
#define RHINO_CONFIG_MM_BLK 1
#endif
#ifndef RHINO_CONFIG_MM_DEBUG
#define RHINO_CONFIG_MM_DEBUG 1
#endif
#ifndef RHINO_CONFIG_MM_TLF
#define RHINO_CONFIG_MM_TLF 1
#endif
#ifndef RHINO_CONFIG_MM_TLF_BLK_SIZE
#define RHINO_CONFIG_MM_TLF_BLK_SIZE 8192
#endif
#define K_MM_STATISTIC 1
#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT
#define RHINO_CONFIG_MM_MAXMSIZEBIT 19
#endif
#ifndef RHINO_CONFIG_GCC_RETADDR
#define RHINO_CONFIG_GCC_RETADDR 1
#endif
#ifndef RHINO_CONFIG_MM_LEAKCHECK
#define RHINO_CONFIG_MM_LEAKCHECK 1
#endif
#ifndef RHINO_CONFIG_RINGBUF_VENDOR
#define RHINO_CONFIG_RINGBUF_VENDOR 0
#endif
#ifndef RHINO_CONFIG_KOBJ_SET
#define RHINO_CONFIG_KOBJ_SET 1
#endif
/* kernel task conf */
#ifndef RHINO_CONFIG_TASK_SUSPEND
#define RHINO_CONFIG_TASK_SUSPEND 1
#endif
#ifndef RHINO_CONFIG_TASK_INFO
#define RHINO_CONFIG_TASK_INFO 1
#endif
#ifndef RHINO_CONFIG_TASK_DEL
#define RHINO_CONFIG_TASK_DEL 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK
#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 1
#endif
#ifndef RHINO_CONFIG_TASK_WAIT_ABORT
#define RHINO_CONFIG_TASK_WAIT_ABORT 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK
#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1
#endif
#ifndef RHINO_CONFIG_SCHED_RR
#define RHINO_CONFIG_SCHED_RR 1
#endif
#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT
#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50
#endif
#ifndef RHINO_CONFIG_PRI_MAX
#define RHINO_CONFIG_PRI_MAX 62
#endif
#ifndef RHINO_CONFIG_USER_PRI_MAX
#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2)
#endif
/* kernel workqueue conf */
#ifndef RHINO_CONFIG_WORKQUEUE
#define RHINO_CONFIG_WORKQUEUE 1
#endif
#ifndef RHINO_CONFIG_WORKQUEUE_STACK_SIZE
#define RHINO_CONFIG_WORKQUEUE_STACK_SIZE 768
#endif
/* kernel mm_region conf */
#ifndef RHINO_CONFIG_MM_REGION_MUTEX
#define RHINO_CONFIG_MM_REGION_MUTEX 0
#endif
/* kernel timer&tick conf */
#ifndef RHINO_CONFIG_HW_COUNT
#define RHINO_CONFIG_HW_COUNT 0
#endif
#ifndef RHINO_CONFIG_TICK_TASK
#define RHINO_CONFIG_TICK_TASK 0
#endif
#if (RHINO_CONFIG_TICK_TASK > 0)
#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE
#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256
#endif
#ifndef RHINO_CONFIG_TICK_TASK_PRI
#define RHINO_CONFIG_TICK_TASK_PRI 1
#endif
#endif
#ifndef RHINO_CONFIG_TICKLESS
#define RHINO_CONFIG_TICKLESS 0
#endif
#ifndef RHINO_CONFIG_TICKS_PER_SECOND
#define RHINO_CONFIG_TICKS_PER_SECOND 500
#endif
/* must be 2^n size!, such as 1, 2, 4, 8, 16,32, etc....... */
#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY
#define RHINO_CONFIG_TICK_HEAD_ARRAY 8
#endif
/*must reserve enough stack size for timer cb will consume*/
#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE
#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 400
#endif
#ifndef RHINO_CONFIG_TIMER_RATE
#define RHINO_CONFIG_TIMER_RATE 1
#endif
#ifndef RHINO_CONFIG_TIMER_TASK_PRI
#define RHINO_CONFIG_TIMER_TASK_PRI 5
#endif
/* kernel intrpt conf */
#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET
#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0
#endif
#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK
#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0
#endif
#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL
#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u
#endif
#ifndef RHINO_CONFIG_INTRPT_GUARD
#define RHINO_CONFIG_INTRPT_GUARD 0
#endif
/* kernel dyn alloc conf */
#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC
#define RHINO_CONFIG_KOBJ_DYN_ALLOC 1
#endif
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG
#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30
#endif
#ifndef RHINO_CONFIG_K_DYN_TASK_STACK
#define RHINO_CONFIG_K_DYN_TASK_STACK 256
#endif
#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI
#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 6
#endif
#endif
/* kernel idle conf */
#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE
#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200
#endif
/* kernel hook conf */
#ifndef RHINO_CONFIG_USER_HOOK
#define RHINO_CONFIG_USER_HOOK 0
#endif
/* kernel stats conf */
#ifndef RHINO_CONFIG_SYSTEM_STATS
#define RHINO_CONFIG_SYSTEM_STATS 1
#endif
#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS
#define RHINO_CONFIG_DISABLE_SCHED_STATS 0
#endif
#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS
#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_STATS
#define RHINO_CONFIG_CPU_USAGE_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI
#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2)
#endif
#ifndef RHINO_CONFIG_TASK_SCHED_STATS
#define RHINO_CONFIG_TASK_SCHED_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK
#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256
#endif
#ifndef RHINO_CONFIG_CPU_NUM
#define RHINO_CONFIG_CPU_NUM 1
#endif
/* kernel trace conf */
#ifndef RHINO_CONFIG_TRACE
#define RHINO_CONFIG_TRACE 0
#endif
#endif /* CONFIG_H */

View file

@ -0,0 +1 @@
linux_only_targets="living_platform linkkit_gateway"

View file

@ -0,0 +1,35 @@
/*
* Script for GNU linker.
* Describes layout of sections, location of stack.
*
* In this case vectors are at location 0 (reset @ 0x08)
*
* +------------+ 0x00400000
* data |
* end
* |(heap) |
* . .
* . .
* |(heap limit)|
*
* |- - - - - - |
* stack bottom 256k
* +------------+
*
* +------------+ 0x0000000
* |vectors |
* | |
* |------------+
* |text |
* |data |
* | | 1024k
* +------------+
*/
/* Split memory into area for vectors and ram */
MEMORY
{
flash (rx) : ORIGIN = 0x00010000, LENGTH = 2M - 64k
ram (rwx): ORIGIN = 0x00400020, LENGTH = 256k - 32
}

View file

@ -0,0 +1,31 @@
NAME := board_bk7231u
JTAG := jlink
$(NAME)_TYPE := kernel
MODULE := BK7231U
HOST_ARCH := ARM968E-S
HOST_MCU_FAMILY := bk7231u
SUPPORT_BINS := no
$(NAME)_SOURCES := board.c
GLOBAL_INCLUDES += .
GLOBAL_DEFINES += STDIO_UART=1
CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_BK7231U
CONFIG_SYSINFO_DEVICE_NAME := BK7231U
GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\"
GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\"
GLOBAL_LDS_INCLUDES += $(SOURCE_ROOT)/board/bk7231udevkitc/bk7231udevkitc.ld
# Extra build target in aos_standard_targets.mk, include bootloader, and copy output file to eclipse debug file (copy_output_for_eclipse)
EXTRA_TARGET_MAKEFILES += $(MAKEFILES_PATH)/aos_standard_targets.mk
ifeq ($(PING_PONG_OTA),1)
EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_pingpong_bin.mk
else
EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_crc_bin.mk
endif

View file

@ -0,0 +1,79 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "hal/soc/soc.h"
#include <aos/kernel.h>
#include <aos/aos.h>
/* Logic partition on flash devices */
const hal_logic_partition_t hal_partitions[] =
{
[HAL_PARTITION_BOOTLOADER] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "Bootloader",
.partition_start_addr = 0x000000,
.partition_length = 0x10000, //64k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_1] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER1",
.partition_start_addr = 0x010000,// boot information need protect
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_APPLICATION] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "Application",
.partition_start_addr = 0x011000,//cpu is 0x10000
.partition_length = 0x113000, //1100k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
/*reserved 52k*/
[HAL_PARTITION_OTA_TEMP] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "OTA Storage",
.partition_start_addr = 0x124000,//cpu is 0xF0000
.partition_length = 0xC9000, //804k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
/*protected flash size is 0~1984k. below are not protected.*/
[HAL_PARTITION_PARAMETER_2] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER2",
.partition_start_addr = 0x1F0000,
.partition_length = 0x2000, // 8k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_PARAMETER_4] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "PARAMETER4",
.partition_start_addr = 0x1F2000,
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
[HAL_PARTITION_RF_FIRMWARE] =
{
.partition_owner = HAL_FLASH_EMBEDDED,
.partition_description = "RF parameter",
.partition_start_addr = 0x1F3000,
.partition_length = 0x1000, // 4k bytes
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN,
},
};
void board_init(void)
{
}
int board_cli_init(void)
{
}

View file

@ -0,0 +1,13 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#define HARDWARE_REVISION "V1.0"
#define MODEL "BK7231U"
#define STDIO_UART 1
#define STDIO_UART_BUADRATE 115200
#define BK_UART 0
#define BK_UART_BUADRATE 115200

View file

@ -0,0 +1,229 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef CONFIG_H
#define CONFIG_H
/* chip level conf */
#ifndef RHINO_CONFIG_LITTLE_ENDIAN
#define RHINO_CONFIG_LITTLE_ENDIAN 1
#endif
#ifndef RHINO_CONFIG_CPU_STACK_DOWN
#define RHINO_CONFIG_CPU_STACK_DOWN 1
#endif
/* kernel feature conf */
#ifndef RHINO_CONFIG_SEM
#define RHINO_CONFIG_SEM 1
#endif
#ifndef RHINO_CONFIG_QUEUE
#define RHINO_CONFIG_QUEUE 1
#endif
#ifndef RHINO_CONFIG_TASK_SEM
#define RHINO_CONFIG_TASK_SEM 1
#endif
#ifndef RHINO_CONFIG_EVENT_FLAG
#define RHINO_CONFIG_EVENT_FLAG 1
#endif
#ifndef RHINO_CONFIG_TIMER
#define RHINO_CONFIG_TIMER 1
#endif
#ifndef RHINO_CONFIG_BUF_QUEUE
#define RHINO_CONFIG_BUF_QUEUE 1
#endif
#ifndef RHINO_CONFIG_MM_BLK
#define RHINO_CONFIG_MM_BLK 1
#endif
#ifndef RHINO_CONFIG_MM_DEBUG
#define RHINO_CONFIG_MM_DEBUG 1
#endif
#ifndef RHINO_CONFIG_MM_TLF
#define RHINO_CONFIG_MM_TLF 1
#endif
#ifndef RHINO_CONFIG_MM_TLF_BLK_SIZE
#define RHINO_CONFIG_MM_TLF_BLK_SIZE 8192
#endif
#define K_MM_STATISTIC 1
#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT
#define RHINO_CONFIG_MM_MAXMSIZEBIT 19
#endif
#ifndef RHINO_CONFIG_GCC_RETADDR
#define RHINO_CONFIG_GCC_RETADDR 1
#endif
#ifndef RHINO_CONFIG_MM_LEAKCHECK
#define RHINO_CONFIG_MM_LEAKCHECK 1
#endif
#ifndef RHINO_CONFIG_RINGBUF_VENDOR
#define RHINO_CONFIG_RINGBUF_VENDOR 0
#endif
#ifndef RHINO_CONFIG_KOBJ_SET
#define RHINO_CONFIG_KOBJ_SET 1
#endif
/* kernel task conf */
#ifndef RHINO_CONFIG_TASK_SUSPEND
#define RHINO_CONFIG_TASK_SUSPEND 1
#endif
#ifndef RHINO_CONFIG_TASK_INFO
#define RHINO_CONFIG_TASK_INFO 1
#endif
#ifndef RHINO_CONFIG_TASK_DEL
#define RHINO_CONFIG_TASK_DEL 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK
#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 1
#endif
#ifndef RHINO_CONFIG_TASK_WAIT_ABORT
#define RHINO_CONFIG_TASK_WAIT_ABORT 1
#endif
#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK
#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1
#endif
#ifndef RHINO_CONFIG_SCHED_RR
#define RHINO_CONFIG_SCHED_RR 1
#endif
#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT
#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50
#endif
#ifndef RHINO_CONFIG_PRI_MAX
#define RHINO_CONFIG_PRI_MAX 62
#endif
#ifndef RHINO_CONFIG_USER_PRI_MAX
#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2)
#endif
/* kernel workqueue conf */
#ifndef RHINO_CONFIG_WORKQUEUE
#define RHINO_CONFIG_WORKQUEUE 1
#endif
#ifndef RHINO_CONFIG_WORKQUEUE_STACK_SIZE
#define RHINO_CONFIG_WORKQUEUE_STACK_SIZE 768
#endif
/* kernel mm_region conf */
#ifndef RHINO_CONFIG_MM_REGION_MUTEX
#define RHINO_CONFIG_MM_REGION_MUTEX 0
#endif
/* kernel timer&tick conf */
#ifndef RHINO_CONFIG_HW_COUNT
#define RHINO_CONFIG_HW_COUNT 0
#endif
#ifndef RHINO_CONFIG_TICK_TASK
#define RHINO_CONFIG_TICK_TASK 0
#endif
#if (RHINO_CONFIG_TICK_TASK > 0)
#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE
#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256
#endif
#ifndef RHINO_CONFIG_TICK_TASK_PRI
#define RHINO_CONFIG_TICK_TASK_PRI 1
#endif
#endif
#ifndef RHINO_CONFIG_TICKLESS
#define RHINO_CONFIG_TICKLESS 0
#endif
#ifndef RHINO_CONFIG_TICKS_PER_SECOND
#define RHINO_CONFIG_TICKS_PER_SECOND 500
#endif
/* must be 2^n size!, such as 1, 2, 4, 8, 16,32, etc....... */
#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY
#define RHINO_CONFIG_TICK_HEAD_ARRAY 8
#endif
/*must reserve enough stack size for timer cb will consume*/
#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE
#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 400
#endif
#ifndef RHINO_CONFIG_TIMER_RATE
#define RHINO_CONFIG_TIMER_RATE 1
#endif
#ifndef RHINO_CONFIG_TIMER_TASK_PRI
#define RHINO_CONFIG_TIMER_TASK_PRI 5
#endif
/* kernel intrpt conf */
#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET
#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0
#endif
#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK
#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0
#endif
#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL
#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u
#endif
#ifndef RHINO_CONFIG_INTRPT_GUARD
#define RHINO_CONFIG_INTRPT_GUARD 0
#endif
/* kernel dyn alloc conf */
#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC
#define RHINO_CONFIG_KOBJ_DYN_ALLOC 1
#endif
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG
#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30
#endif
#ifndef RHINO_CONFIG_K_DYN_TASK_STACK
#define RHINO_CONFIG_K_DYN_TASK_STACK 256
#endif
#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI
#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 6
#endif
#endif
/* kernel idle conf */
#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE
#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200
#endif
/* kernel hook conf */
#ifndef RHINO_CONFIG_USER_HOOK
#define RHINO_CONFIG_USER_HOOK 0
#endif
/* kernel stats conf */
#ifndef RHINO_CONFIG_SYSTEM_STATS
#define RHINO_CONFIG_SYSTEM_STATS 1
#endif
#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS
#define RHINO_CONFIG_DISABLE_SCHED_STATS 0
#endif
#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS
#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_STATS
#define RHINO_CONFIG_CPU_USAGE_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI
#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2)
#endif
#ifndef RHINO_CONFIG_TASK_SCHED_STATS
#define RHINO_CONFIG_TASK_SCHED_STATS 0
#endif
#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK
#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256
#endif
#ifndef RHINO_CONFIG_CPU_NUM
#define RHINO_CONFIG_CPU_NUM 1
#endif
#ifndef WIFI_CONFIG_LISTEN_INTERVAL
#define WIFI_CONFIG_LISTEN_INTERVAL 1
#endif
/* kernel trace conf */
#ifndef RHINO_CONFIG_TRACE
#define RHINO_CONFIG_TRACE 0
#endif
#endif /* CONFIG_H */

View file

@ -0,0 +1 @@
linux_only_targets="living_platform linkkit_gateway smart_outlet smart_outlet_meter smart_led_bulb smart_led_strip"

View file

@ -0,0 +1,141 @@
/**
******************************************************************************
* @file : main.h
* @brief : Header for main.c file.
* This file contains the common defines of the application.
******************************************************************************
** This notice applies to any and all portions of this file
* that are not between comment pairs USER CODE BEGIN and
* USER CODE END. Other portions of this file, whether
* inserted by the user or by software development tools
* are owned by their respective copyright owners.
*
* COPYRIGHT(c) 2018 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H__
#define __MAIN_H__
/* Includes ------------------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private define ------------------------------------------------------------*/
#define SIM_DET_Pin GPIO_PIN_2
#define SIM_DET_GPIO_Port GPIOE
#define AUDIO_CTL_Pin GPIO_PIN_3
#define AUDIO_CTL_GPIO_Port GPIOE
#define PCIE_RST_Pin GPIO_PIN_13
#define PCIE_RST_GPIO_Port GPIOC
#define SECURE_IO_Pin GPIO_PIN_0
#define SECURE_IO_GPIO_Port GPIOA
#define SECURE_RST_Pin GPIO_PIN_1
#define SECURE_RST_GPIO_Port GPIOA
#define LCD_DCX_Pin GPIO_PIN_6
#define LCD_DCX_GPIO_Port GPIOA
#define WIFI_RST_Pin GPIO_PIN_0
#define WIFI_RST_GPIO_Port GPIOB
#define WIFI_WU_Pin GPIO_PIN_1
#define WIFI_WU_GPIO_Port GPIOB
#define LCD_RST_Pin GPIO_PIN_2
#define LCD_RST_GPIO_Port GPIOB
#define LCD_PWR_Pin GPIO_PIN_7
#define LCD_PWR_GPIO_Port GPIOE
#define ZIGBEE_INT_Pin GPIO_PIN_8
#define ZIGBEE_INT_GPIO_Port GPIOE
#define ZIGBEE_INT_EXTI_IRQn EXTI9_5_IRQn
#define KEY_2_Pin GPIO_PIN_9
#define KEY_2_GPIO_Port GPIOE
#define KEY_2_EXTI_IRQn EXTI9_5_IRQn
#define KEY_3_Pin GPIO_PIN_10
#define KEY_3_GPIO_Port GPIOE
#define KEY_3_EXTI_IRQn EXTI15_10_IRQn
#define KEY_1_Pin GPIO_PIN_11
#define KEY_1_GPIO_Port GPIOE
#define KEY_1_EXTI_IRQn EXTI15_10_IRQn
#define CAM_PD_Pin GPIO_PIN_13
#define CAM_PD_GPIO_Port GPIOE
#define AUDIO_RST_Pin GPIO_PIN_14
#define AUDIO_RST_GPIO_Port GPIOE
#define SECURE_CLK_Pin GPIO_PIN_15
#define SECURE_CLK_GPIO_Port GPIOE
#define HTS_LED_Pin GPIO_PIN_11
#define HTS_LED_GPIO_Port GPIOD
#define GS_LED_Pin GPIO_PIN_12
#define GS_LED_GPIO_Port GPIOD
#define ALS_LED_Pin GPIO_PIN_13
#define ALS_LED_GPIO_Port GPIOD
#define PS_LED_Pin GPIO_PIN_14
#define PS_LED_GPIO_Port GPIOD
#define COMPASS_LED_Pin GPIO_PIN_15
#define COMPASS_LED_GPIO_Port GPIOD
#define CAM_MCLK_Pin GPIO_PIN_8
#define CAM_MCLK_GPIO_Port GPIOA
#define ALS_INT_Pin GPIO_PIN_15
#define ALS_INT_GPIO_Port GPIOA
#define ALS_INT_EXTI_IRQn EXTI15_10_IRQn
#define AUDIO_WU_Pin GPIO_PIN_4
#define AUDIO_WU_GPIO_Port GPIOD
#define IRDA_CTL_Pin GPIO_PIN_5
#define IRDA_CTL_GPIO_Port GPIOD
#define IRDA_RX_Pin GPIO_PIN_6
#define IRDA_RX_GPIO_Port GPIOD
#define ZIGBEE_RST_Pin GPIO_PIN_7
#define ZIGBEE_RST_GPIO_Port GPIOD
#define USB_PCIE_SW_Pin GPIO_PIN_5
#define USB_PCIE_SW_GPIO_Port GPIOB
#define CAM_RST_Pin GPIO_PIN_8
#define CAM_RST_GPIO_Port GPIOB
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
extern "C" {
#endif
void _Error_Handler(char *, int);
#define Error_Handler() _Error_Handler(__FILE__, __LINE__)
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,430 @@
/**
******************************************************************************
* @file stm32l4xx_hal_conf.h
* @brief HAL configuration file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32L4xx_HAL_CONF_H
#define __STM32L4xx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
#define HAL_ADC_MODULE_ENABLED
/*#define HAL_CRYP_MODULE_ENABLED */
/*#define HAL_CAN_MODULE_ENABLED */
/*#define HAL_COMP_MODULE_ENABLED */
#define HAL_CRC_MODULE_ENABLED
/*#define HAL_CRYP_MODULE_ENABLED */
/*#define HAL_DAC_MODULE_ENABLED */
#define HAL_DCMI_MODULE_ENABLED
/*#define HAL_DMA2D_MODULE_ENABLED */
/*#define HAL_DFSDM_MODULE_ENABLED */
/*#define HAL_DSI_MODULE_ENABLED */
/*#define HAL_FIREWALL_MODULE_ENABLED */
/*#define HAL_GFXMMU_MODULE_ENABLED */
/*#define HAL_HCD_MODULE_ENABLED */
/*#define HAL_HASH_MODULE_ENABLED */
/*#define HAL_I2S_MODULE_ENABLED */
/*#define HAL_IRDA_MODULE_ENABLED */
/*#define HAL_IWDG_MODULE_ENABLED */
/*#define HAL_LTDC_MODULE_ENABLED */
/*#define HAL_LCD_MODULE_ENABLED */
/*#define HAL_LPTIM_MODULE_ENABLED */
/*#define HAL_NAND_MODULE_ENABLED */
/*#define HAL_NOR_MODULE_ENABLED */
/*#define HAL_OPAMP_MODULE_ENABLED */
/*#define HAL_OSPI_MODULE_ENABLED */
/*#define HAL_OSPI_MODULE_ENABLED */
/*#define HAL_PCD_MODULE_ENABLED */
/*#define HAL_QSPI_MODULE_ENABLED */
/*#define HAL_QSPI_MODULE_ENABLED */
/*#define HAL_RNG_MODULE_ENABLED */
/*#define HAL_RTC_MODULE_ENABLED */
#define HAL_SAI_MODULE_ENABLED
/*#define HAL_SD_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
#define HAL_SPI_MODULE_ENABLED
/*#define HAL_SRAM_MODULE_ENABLED */
/*#define HAL_SWPMI_MODULE_ENABLED */
/*#define HAL_TIM_MODULE_ENABLED */
/*#define HAL_TSC_MODULE_ENABLED */
#define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_I2C_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
/* ########################## Oscillator Values adaptation ####################*/
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal Multiple Speed oscillator (MSI) default value.
* This value is the default MSI range value after Reset.
*/
#if !defined (MSI_VALUE)
#define MSI_VALUE ((uint32_t)4000000U) /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG.
* This internal oscillator is mainly dedicated to provide a high precision clock to
* the USB peripheral by means of a special Clock Recovery System (CRS) circuitry.
* When the CRS is not used, the HSI48 RC oscillator runs on it default frequency
* which is subject to manufacturing process variations.
*/
#if !defined (HSI48_VALUE)
#define HSI48_VALUE ((uint32_t)48000000U) /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz.
The real value my vary depending on manufacturing process variations.*/
#endif /* HSI48_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
#if !defined (LSI_VALUE)
#define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief External Low Speed oscillator (LSE) value.
* This value is used by the UART, RTC HAL module to compute the system frequency
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for SAI1 peripheral
* This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
* frequency.
*/
#if !defined (EXTERNAL_SAI1_CLOCK_VALUE)
#define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t)2097000U) /*!< Value of the SAI1 External clock source in Hz*/
#endif /* EXTERNAL_SAI1_CLOCK_VALUE */
/**
* @brief External clock source for SAI2 peripheral
* This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
* frequency.
*/
#if !defined (EXTERNAL_SAI2_CLOCK_VALUE)
#define EXTERNAL_SAI2_CLOCK_VALUE ((uint32_t)2097000U) /*!< Value of the SAI2 External clock source in Hz*/
#endif /* EXTERNAL_SAI2_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 0U
#define INSTRUCTION_CACHE_ENABLE 1U
#define DATA_CACHE_ENABLE 1U
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 0U
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32l4xx_hal_rcc.h"
#include "stm32l4xx_hal_rcc_ex.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32l4xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32l4xx_hal_dma.h"
#include "stm32l4xx_hal_dma_ex.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_DFSDM_MODULE_ENABLED
#include "stm32l4xx_hal_dfsdm.h"
#endif /* HAL_DFSDM_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32l4xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32l4xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CAN_MODULE_ENABLED
#include "stm32l4xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */
#ifdef HAL_COMP_MODULE_ENABLED
#include "stm32l4xx_hal_comp.h"
#endif /* HAL_COMP_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32l4xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32l4xx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED
#include "stm32l4xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_DCMI_MODULE_ENABLED
#include "stm32l4xx_hal_dcmi.h"
#endif /* HAL_DCMI_MODULE_ENABLED */
#ifdef HAL_DMA2D_MODULE_ENABLED
#include "stm32l4xx_hal_dma2d.h"
#endif /* HAL_DMA2D_MODULE_ENABLED */
#ifdef HAL_DSI_MODULE_ENABLED
#include "stm32l4xx_hal_dsi.h"
#endif /* HAL_DSI_MODULE_ENABLED */
#ifdef HAL_FIREWALL_MODULE_ENABLED
#include "stm32l4xx_hal_firewall.h"
#endif /* HAL_FIREWALL_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32l4xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_HASH_MODULE_ENABLED
#include "stm32l4xx_hal_hash.h"
#endif /* HAL_HASH_MODULE_ENABLED */
#ifdef HAL_SRAM_MODULE_ENABLED
#include "stm32l4xx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */
#ifdef HAL_NOR_MODULE_ENABLED
#include "stm32l4xx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */
#ifdef HAL_NAND_MODULE_ENABLED
#include "stm32l4xx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32l4xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32l4xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LCD_MODULE_ENABLED
#include "stm32l4xx_hal_lcd.h"
#endif /* HAL_LCD_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32l4xx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
#ifdef HAL_LTDC_MODULE_ENABLED
#include "stm32l4xx_hal_ltdc.h"
#endif /* HAL_LTDC_MODULE_ENABLED */
#ifdef HAL_OPAMP_MODULE_ENABLED
#include "stm32l4xx_hal_opamp.h"
#endif /* HAL_OPAMP_MODULE_ENABLED */
#ifdef HAL_OSPI_MODULE_ENABLED
#include "stm32l4xx_hal_ospi.h"
#endif /* HAL_OSPI_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32l4xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_QSPI_MODULE_ENABLED
#include "stm32l4xx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32l4xx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32l4xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
#include "stm32l4xx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SD_MODULE_ENABLED
#include "stm32l4xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32l4xx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32l4xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_SWPMI_MODULE_ENABLED
#include "stm32l4xx_hal_swpmi.h"
#endif /* HAL_SWPMI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32l4xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_TSC_MODULE_ENABLED
#include "stm32l4xx_hal_tsc.h"
#endif /* HAL_TSC_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32l4xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32l4xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32l4xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32l4xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32l4xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32l4xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
#include "stm32l4xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_GFXMMU_MODULE_ENABLED
#include "stm32l4xx_hal_gfxmmu.h"
#endif /* HAL_GFXMMU_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr: If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* __STM32L4xx_HAL_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,71 @@
/**
******************************************************************************
* @file stm32l4xx_it.h
* @brief This file contains the headers of the interrupt handlers.
******************************************************************************
*
* COPYRIGHT(c) 2018 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32L4xx_IT_H
#define __STM32L4xx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"
#include "main.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void EXTI9_5_IRQHandler(void);
void USART2_IRQHandler(void);
void USART3_IRQHandler(void);
void EXTI15_10_IRQHandler(void);
void LPUART1_IRQHandler(void);
#ifdef __cplusplus
}
#endif
#endif /* __STM32L4xx_IT_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,15 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x00100000 { ; load region size_region
ER_IROM1 0x08000000 0x00100000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00050000 { ; RW data
.ANY (+RW +ZI)
}
}

View file

@ -0,0 +1,183 @@
/*
*****************************************************************************
**
** File : LinkerScript.ld
**
** Abstract : Linker script for STM32L496VGTx Device with
** 1024KByte FLASH, 320KByte RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
**
** Distribution: The file is distributed as is, without any warranty
** of any kind.
**
** (c)Copyright Ac6.
** You may use this file as-is or modify it according to the needs of your
** project. Distribution of this file (unmodified or modified) is not
** permitted. Ac6 permit registered System Workbench for MCU users the
** rights to distribute the assembled, compiled & linked contents of this
** file as part of an application binary file, provided that it is built
** using the System Workbench for MCU toolchain.
**
*****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20050000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(8);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(8);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(8);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(8);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data goes into FLASH */
.rodata :
{
. = ALIGN(8);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(8);
} >FLASH
.ARM.extab :
{
. = ALIGN(8);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(8);
} >FLASH
.ARM : {
. = ALIGN(8);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(8);
} >FLASH
.preinit_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(8);
} >FLASH
.init_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(8);
} >FLASH
.fini_array :
{
. = ALIGN(8);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(8);
} >FLASH
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
{
. = ALIGN(8);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(8);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View file

@ -0,0 +1,776 @@
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
** This notice applies to any and all portions of this file
* that are not between comment pairs USER CODE BEGIN and
* USER CODE END. Other portions of this file, whether
* inserted by the user or by software development tools
* are owned by their respective copyright owners.
*
* COPYRIGHT(c) 2018 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l4xx_hal.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc3;
CRC_HandleTypeDef hcrc;
DCMI_HandleTypeDef hdcmi;
I2C_HandleTypeDef hi2c1;
I2C_HandleTypeDef hi2c2;
I2C_HandleTypeDef hi2c3;
UART_HandleTypeDef hlpuart1;
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3;
SAI_HandleTypeDef hsai_BlockA2;
SPI_HandleTypeDef hspi1;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C3_Init(void);
static void MX_I2C1_Init(void);
static void MX_I2C2_Init(void);
static void MX_ADC3_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_LPUART1_UART_Init(void);
static void MX_SAI2_Init(void);
static void MX_DCMI_Init(void);
static void MX_USB_OTG_FS_USB_Init(void);
static void MX_SDMMC1_Init(void);
static void MX_CRC_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
*
* @retval None
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C3_Init();
MX_I2C1_Init();
MX_I2C2_Init();
MX_ADC3_Init();
MX_USART2_UART_Init();
MX_SPI1_Init();
MX_USART3_UART_Init();
MX_LPUART1_UART_Init();
MX_SAI2_Init();
MX_DCMI_Init();
MX_USB_OTG_FS_USB_Init();
MX_SDMMC1_Init();
MX_CRC_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
/**Configure LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_USART3
|RCC_PERIPHCLK_LPUART1|RCC_PERIPHCLK_SAI2
|RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_I2C2
|RCC_PERIPHCLK_I2C3|RCC_PERIPHCLK_USB
|RCC_PERIPHCLK_SDMMC1|RCC_PERIPHCLK_ADC;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
PeriphClkInit.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1;
PeriphClkInit.I2c3ClockSelection = RCC_I2C3CLKSOURCE_PCLK1;
PeriphClkInit.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLSAI1;
PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLLSAI1;
PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI;
PeriphClkInit.PLLSAI1.PLLSAI1M = 1;
PeriphClkInit.PLLSAI1.PLLSAI1N = 24;
PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK|RCC_PLLSAI1_48M2CLK
|RCC_PLLSAI1_ADC1CLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/8000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);
/**Enable MSI Auto calibration
*/
HAL_RCCEx_EnableMSIPLLMode();
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* ADC3 init function */
static void MX_ADC3_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
/**Common config
*/
hadc3.Instance = ADC3;
hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc3.Init.Resolution = ADC_RESOLUTION_12B;
hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc3.Init.LowPowerAutoWait = DISABLE;
hadc3.Init.ContinuousConvMode = DISABLE;
hadc3.Init.NbrOfConversion = 1;
hadc3.Init.DiscontinuousConvMode = DISABLE;
hadc3.Init.NbrOfDiscConversion = 1;
hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc3.Init.DMAContinuousRequests = DISABLE;
hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc3.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
sConfig.SingleDiff = ADC_DIFFERENTIAL_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* CRC init function */
static void MX_CRC_Init(void)
{
hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
if (HAL_CRC_Init(&hcrc) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* DCMI init function */
static void MX_DCMI_Init(void)
{
hdcmi.Instance = DCMI;
hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING;
hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_LOW;
hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;
hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE;
hdcmi.Init.ByteSelectMode = DCMI_BSM_ALL;
hdcmi.Init.ByteSelectStart = DCMI_OEBS_ODD;
hdcmi.Init.LineSelectMode = DCMI_LSM_ALL;
hdcmi.Init.LineSelectStart = DCMI_OELS_ODD;
if (HAL_DCMI_Init(&hdcmi) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* I2C1 init function */
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x10909CEC;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* I2C2 init function */
static void MX_I2C2_Init(void)
{
hi2c2.Instance = I2C2;
hi2c2.Init.Timing = 0x10909CEC;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* I2C3 init function */
static void MX_I2C3_Init(void)
{
hi2c3.Instance = I2C3;
hi2c3.Init.Timing = 0x10909CEC;
hi2c3.Init.OwnAddress1 = 0;
hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c3.Init.OwnAddress2 = 0;
hi2c3.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c3, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c3, 0) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* LPUART1 init function */
static void MX_LPUART1_UART_Init(void)
{
hlpuart1.Instance = LPUART1;
hlpuart1.Init.BaudRate = 115200;
hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
hlpuart1.Init.StopBits = UART_STOPBITS_1;
hlpuart1.Init.Parity = UART_PARITY_NONE;
hlpuart1.Init.Mode = UART_MODE_TX_RX;
hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&hlpuart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* USART2 init function */
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* USART3 init function */
static void MX_USART3_UART_Init(void)
{
huart3.Instance = USART3;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* SAI2 init function */
static void MX_SAI2_Init(void)
{
hsai_BlockA2.Instance = SAI2_Block_A;
hsai_BlockA2.Init.Protocol = SAI_FREE_PROTOCOL;
hsai_BlockA2.Init.AudioMode = SAI_MODEMASTER_TX;
hsai_BlockA2.Init.DataSize = SAI_DATASIZE_24;
hsai_BlockA2.Init.FirstBit = SAI_FIRSTBIT_MSB;
hsai_BlockA2.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
hsai_BlockA2.Init.Synchro = SAI_ASYNCHRONOUS;
hsai_BlockA2.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
hsai_BlockA2.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
hsai_BlockA2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
hsai_BlockA2.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_192K;
hsai_BlockA2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
hsai_BlockA2.Init.MonoStereoMode = SAI_STEREOMODE;
hsai_BlockA2.Init.CompandingMode = SAI_NOCOMPANDING;
hsai_BlockA2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
hsai_BlockA2.FrameInit.FrameLength = 8;
hsai_BlockA2.FrameInit.ActiveFrameLength = 1;
hsai_BlockA2.FrameInit.FSDefinition = SAI_FS_STARTFRAME;
hsai_BlockA2.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
hsai_BlockA2.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
hsai_BlockA2.SlotInit.FirstBitOffset = 0;
hsai_BlockA2.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
hsai_BlockA2.SlotInit.SlotNumber = 1;
hsai_BlockA2.SlotInit.SlotActive = 0x00000000;
if (HAL_SAI_Init(&hsai_BlockA2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* SDMMC1 init function */
static void MX_SDMMC1_Init(void)
{
}
/* SPI1 init function */
static void MX_SPI1_Init(void)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_1LINE;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* USB_OTG_FS init function */
static void MX_USB_OTG_FS_USB_Init(void)
{
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
PC8 ------> SDMMC1_D0
PC9 ------> SDMMC1_D1
PA10 ------> USB_OTG_FS_ID
PA11 ------> USB_OTG_FS_DM
PA12 ------> USB_OTG_FS_DP
PC10 ------> SDMMC1_D2
PC11 ------> SDMMC1_D3
PC12 ------> SDMMC1_CK
PD2 ------> SDMMC1_CMD
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOE, AUDIO_CTL_Pin|LCD_PWR_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(PCIE_RST_GPIO_Port, PCIE_RST_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, SECURE_IO_Pin|SECURE_RST_Pin|LCD_DCX_Pin|CAM_MCLK_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, WIFI_RST_Pin|WIFI_WU_Pin|LCD_RST_Pin|USB_PCIE_SW_Pin
|CAM_RST_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOE, CAM_PD_Pin|AUDIO_RST_Pin|SECURE_CLK_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, HTS_LED_Pin|GS_LED_Pin|ALS_LED_Pin|PS_LED_Pin
|COMPASS_LED_Pin|AUDIO_WU_Pin|ZIGBEE_RST_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(IRDA_CTL_GPIO_Port, IRDA_CTL_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : SIM_DET_Pin */
GPIO_InitStruct.Pin = SIM_DET_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SIM_DET_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : AUDIO_CTL_Pin LCD_PWR_Pin CAM_PD_Pin AUDIO_RST_Pin
SECURE_CLK_Pin */
GPIO_InitStruct.Pin = AUDIO_CTL_Pin|LCD_PWR_Pin|CAM_PD_Pin|AUDIO_RST_Pin
|SECURE_CLK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pin : PCIE_RST_Pin */
GPIO_InitStruct.Pin = PCIE_RST_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(PCIE_RST_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : SECURE_IO_Pin SECURE_RST_Pin LCD_DCX_Pin CAM_MCLK_Pin */
GPIO_InitStruct.Pin = SECURE_IO_Pin|SECURE_RST_Pin|LCD_DCX_Pin|CAM_MCLK_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : WIFI_RST_Pin WIFI_WU_Pin LCD_RST_Pin USB_PCIE_SW_Pin
CAM_RST_Pin */
GPIO_InitStruct.Pin = WIFI_RST_Pin|WIFI_WU_Pin|LCD_RST_Pin|USB_PCIE_SW_Pin
|CAM_RST_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : ZIGBEE_INT_Pin KEY_2_Pin KEY_3_Pin KEY_1_Pin */
GPIO_InitStruct.Pin = ZIGBEE_INT_Pin|KEY_2_Pin|KEY_3_Pin|KEY_1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pins : HTS_LED_Pin GS_LED_Pin ALS_LED_Pin PS_LED_Pin
COMPASS_LED_Pin AUDIO_WU_Pin IRDA_CTL_Pin ZIGBEE_RST_Pin */
GPIO_InitStruct.Pin = HTS_LED_Pin|GS_LED_Pin|ALS_LED_Pin|PS_LED_Pin
|COMPASS_LED_Pin|AUDIO_WU_Pin|IRDA_CTL_Pin|ZIGBEE_RST_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/*Configure GPIO pins : PC8 PC9 PC10 PC11
PC12 */
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : PA10 PA11 PA12 */
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : ALS_INT_Pin */
GPIO_InitStruct.Pin = ALS_INT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(ALS_INT_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PD2 */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/*Configure GPIO pin : IRDA_RX_Pin */
GPIO_InitStruct.Pin = IRDA_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(IRDA_RX_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @param file: The file name as string.
* @param line: The line in file as a number.
* @retval None
*/
void _Error_Handler(char *file, int line)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,713 @@
/**
******************************************************************************
* File Name : stm32l4xx_hal_msp.c
* Description : This file provides code for the MSP Initialization
* and de-Initialization codes.
******************************************************************************
** This notice applies to any and all portions of this file
* that are not between comment pairs USER CODE BEGIN and
* USER CODE END. Other portions of this file, whether
* inserted by the user or by software development tools
* are owned by their respective copyright owners.
*
* COPYRIGHT(c) 2018 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"
extern void _Error_Handler(char *, int);
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
/* System interrupt init*/
/* MemoryManagement_IRQn interrupt configuration */
HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
/* BusFault_IRQn interrupt configuration */
HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
/* UsageFault_IRQn interrupt configuration */
HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
/* SVCall_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0);
/* DebugMonitor_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
/* PendSV_IRQn interrupt configuration */
HAL_NVIC_SetPriority(PendSV_IRQn, 0, 0);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hadc->Instance==ADC3)
{
/* USER CODE BEGIN ADC3_MspInit 0 */
/* USER CODE END ADC3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_ADC_CLK_ENABLE();
/**ADC3 GPIO Configuration
PC2 ------> ADC3_IN3
PC3 ------> ADC3_IN4
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USER CODE BEGIN ADC3_MspInit 1 */
/* USER CODE END ADC3_MspInit 1 */
}
}
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC3)
{
/* USER CODE BEGIN ADC3_MspDeInit 0 */
/* USER CODE END ADC3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ADC_CLK_DISABLE();
/**ADC3 GPIO Configuration
PC2 ------> ADC3_IN3
PC3 ------> ADC3_IN4
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_2|GPIO_PIN_3);
/* USER CODE BEGIN ADC3_MspDeInit 1 */
/* USER CODE END ADC3_MspDeInit 1 */
}
}
void HAL_CRC_MspInit(CRC_HandleTypeDef* hcrc)
{
if(hcrc->Instance==CRC)
{
/* USER CODE BEGIN CRC_MspInit 0 */
/* USER CODE END CRC_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CRC_CLK_ENABLE();
/* USER CODE BEGIN CRC_MspInit 1 */
/* USER CODE END CRC_MspInit 1 */
}
}
void HAL_CRC_MspDeInit(CRC_HandleTypeDef* hcrc)
{
if(hcrc->Instance==CRC)
{
/* USER CODE BEGIN CRC_MspDeInit 0 */
/* USER CODE END CRC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CRC_CLK_DISABLE();
/* USER CODE BEGIN CRC_MspDeInit 1 */
/* USER CODE END CRC_MspDeInit 1 */
}
}
void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hdcmi->Instance==DCMI)
{
/* USER CODE BEGIN DCMI_MspInit 0 */
/* USER CODE END DCMI_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_DCMI_CLK_ENABLE();
/**DCMI GPIO Configuration
PE4 ------> DCMI_D4
PE5 ------> DCMI_D6
PE6 ------> DCMI_D7
PD8 ------> DCMI_HSYNC
PD9 ------> DCMI_PIXCLK
PC7 ------> DCMI_D1
PA9 ------> DCMI_D0
PD3 ------> DCMI_D5
PB7 ------> DCMI_VSYNC
PE0 ------> DCMI_D2
PE1 ------> DCMI_D3
*/
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_0
|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF10_DCMI;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF10_DCMI;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF10_DCMI;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_DCMI;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_DCMI;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF10_DCMI;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN DCMI_MspInit 1 */
/* USER CODE END DCMI_MspInit 1 */
}
}
void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef* hdcmi)
{
if(hdcmi->Instance==DCMI)
{
/* USER CODE BEGIN DCMI_MspDeInit 0 */
/* USER CODE END DCMI_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_DCMI_CLK_DISABLE();
/**DCMI GPIO Configuration
PE4 ------> DCMI_D4
PE5 ------> DCMI_D6
PE6 ------> DCMI_D7
PD8 ------> DCMI_HSYNC
PD9 ------> DCMI_PIXCLK
PC7 ------> DCMI_D1
PA9 ------> DCMI_D0
PD3 ------> DCMI_D5
PB7 ------> DCMI_VSYNC
PE0 ------> DCMI_D2
PE1 ------> DCMI_D3
*/
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_0
|GPIO_PIN_1);
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_3);
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_7);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);
/* USER CODE BEGIN DCMI_MspDeInit 1 */
/* USER CODE END DCMI_MspDeInit 1 */
}
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB9 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
else if(hi2c->Instance==I2C2)
{
/* USER CODE BEGIN I2C2_MspInit 0 */
/* USER CODE END I2C2_MspInit 0 */
/**I2C2 GPIO Configuration
PB13 ------> I2C2_SCL
PB14 ------> I2C2_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C2_CLK_ENABLE();
/* USER CODE BEGIN I2C2_MspInit 1 */
/* USER CODE END I2C2_MspInit 1 */
}
else if(hi2c->Instance==I2C3)
{
/* USER CODE BEGIN I2C3_MspInit 0 */
/* USER CODE END I2C3_MspInit 0 */
/**I2C3 GPIO Configuration
PC0 ------> I2C3_SCL
PC1 ------> I2C3_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C3_CLK_ENABLE();
/* USER CODE BEGIN I2C3_MspInit 1 */
/* USER CODE END I2C3_MspInit 1 */
}
}
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspDeInit 0 */
/* USER CODE END I2C1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C1_CLK_DISABLE();
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB9 ------> I2C1_SDA
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_9);
/* USER CODE BEGIN I2C1_MspDeInit 1 */
/* USER CODE END I2C1_MspDeInit 1 */
}
else if(hi2c->Instance==I2C2)
{
/* USER CODE BEGIN I2C2_MspDeInit 0 */
/* USER CODE END I2C2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C2_CLK_DISABLE();
/**I2C2 GPIO Configuration
PB13 ------> I2C2_SCL
PB14 ------> I2C2_SDA
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_14);
/* USER CODE BEGIN I2C2_MspDeInit 1 */
/* USER CODE END I2C2_MspDeInit 1 */
}
else if(hi2c->Instance==I2C3)
{
/* USER CODE BEGIN I2C3_MspDeInit 0 */
/* USER CODE END I2C3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C3_CLK_DISABLE();
/**I2C3 GPIO Configuration
PC0 ------> I2C3_SCL
PC1 ------> I2C3_SDA
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_1);
/* USER CODE BEGIN I2C3_MspDeInit 1 */
/* USER CODE END I2C3_MspDeInit 1 */
}
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==LPUART1)
{
/* USER CODE BEGIN LPUART1_MspInit 0 */
/* USER CODE END LPUART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_LPUART1_CLK_ENABLE();
/**LPUART1 GPIO Configuration
PB10 ------> LPUART1_RX
PB11 ------> LPUART1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* LPUART1 interrupt Init */
HAL_NVIC_SetPriority(LPUART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(LPUART1_IRQn);
/* USER CODE BEGIN LPUART1_MspInit 1 */
/* USER CODE END LPUART1_MspInit 1 */
}
else if(huart->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
else if(huart->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspInit 0 */
/* USER CODE END USART3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART3_CLK_ENABLE();
/**USART3 GPIO Configuration
PC4 ------> USART3_TX
PC5 ------> USART3_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspInit 1 */
/* USER CODE END USART3_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{
if(huart->Instance==LPUART1)
{
/* USER CODE BEGIN LPUART1_MspDeInit 0 */
/* USER CODE END LPUART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_LPUART1_CLK_DISABLE();
/**LPUART1 GPIO Configuration
PB10 ------> LPUART1_RX
PB11 ------> LPUART1_TX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
/* LPUART1 interrupt DeInit */
HAL_NVIC_DisableIRQ(LPUART1_IRQn);
/* USER CODE BEGIN LPUART1_MspDeInit 1 */
/* USER CODE END LPUART1_MspDeInit 1 */
}
else if(huart->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspDeInit 0 */
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/* USART2 interrupt DeInit */
HAL_NVIC_DisableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspDeInit 1 */
/* USER CODE END USART2_MspDeInit 1 */
}
else if(huart->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspDeInit 0 */
/* USER CODE END USART3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART3_CLK_DISABLE();
/**USART3 GPIO Configuration
PC4 ------> USART3_TX
PC5 ------> USART3_RX
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_4|GPIO_PIN_5);
/* USART3 interrupt DeInit */
HAL_NVIC_DisableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspDeInit 1 */
/* USER CODE END USART3_MspDeInit 1 */
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA4 ------> SPI1_NSS
PA5 ------> SPI1_SCK
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
{
if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspDeInit 0 */
/* USER CODE END SPI1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI1_CLK_DISABLE();
/**SPI1 GPIO Configuration
PA4 ------> SPI1_NSS
PA5 ------> SPI1_SCK
PA7 ------> SPI1_MOSI
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7);
/* USER CODE BEGIN SPI1_MspDeInit 1 */
/* USER CODE END SPI1_MspDeInit 1 */
}
}
static uint32_t SAI2_client =0;
void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* SAI2 */
if(hsai->Instance==SAI2_Block_A)
{
/* Peripheral clock enable */
if (SAI2_client == 0)
{
__HAL_RCC_SAI2_CLK_ENABLE();
}
SAI2_client ++;
/**SAI2_A_Block_A GPIO Configuration
PB12 ------> SAI2_FS_A
PB15 ------> SAI2_SD_A
PD10 ------> SAI2_SCK_A
PC6 ------> SAI2_MCLK_A
*/
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF13_SAI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF13_SAI2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF13_SAI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
}
void HAL_SAI_MspDeInit(SAI_HandleTypeDef* hsai)
{
/* SAI2 */
if(hsai->Instance==SAI2_Block_A)
{
SAI2_client --;
if (SAI2_client == 0)
{
/* Peripheral clock disable */
__HAL_RCC_SAI2_CLK_DISABLE();
}
/**SAI2_A_Block_A GPIO Configuration
PB12 ------> SAI2_FS_A
PB15 ------> SAI2_SD_A
PD10 ------> SAI2_SCK_A
PC6 ------> SAI2_MCLK_A
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_15);
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_10);
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6);
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,273 @@
/**
******************************************************************************
* @file stm32l4xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
*
* COPYRIGHT(c) 2018 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"
#include "stm32l4xx.h"
#include "stm32l4xx_it.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern UART_HandleTypeDef hlpuart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
/* USER CODE BEGIN HardFault_IRQn 1 */
/* USER CODE END HardFault_IRQn 1 */
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
/* USER CODE BEGIN MemoryManagement_IRQn 1 */
/* USER CODE END MemoryManagement_IRQn 1 */
}
/**
* @brief This function handles Prefetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
/* USER CODE BEGIN BusFault_IRQn 1 */
/* USER CODE END BusFault_IRQn 1 */
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
/* USER CODE BEGIN UsageFault_IRQn 1 */
/* USER CODE END UsageFault_IRQn 1 */
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32L4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32l4xx.s). */
/******************************************************************************/
/**
* @brief This function handles EXTI line[9:5] interrupts.
*/
void EXTI9_5_IRQHandler(void)
{
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
/* USER CODE END EXTI9_5_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
/* USER CODE END EXTI9_5_IRQn 1 */
}
/**
* @brief This function handles USART2 global interrupt.
*/
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
/**
* @brief This function handles USART3 global interrupt.
*/
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */
/* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3);
/* USER CODE BEGIN USART3_IRQn 1 */
/* USER CODE END USART3_IRQn 1 */
}
/**
* @brief This function handles EXTI line[15:10] interrupts.
*/
void EXTI15_10_IRQHandler(void)
{
/* USER CODE BEGIN EXTI15_10_IRQn 0 */
/* USER CODE END EXTI15_10_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
/* USER CODE BEGIN EXTI15_10_IRQn 1 */
/* USER CODE END EXTI15_10_IRQn 1 */
}
/**
* @brief This function handles LPUART1 global interrupt.
*/
void LPUART1_IRQHandler(void)
{
/* USER CODE BEGIN LPUART1_IRQn 0 */
/* USER CODE END LPUART1_IRQn 0 */
HAL_UART_IRQHandler(&hlpuart1);
/* USER CODE BEGIN LPUART1_IRQn 1 */
/* USER CODE END LPUART1_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,353 @@
/**
******************************************************************************
* @file system_stm32l4xx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32l4xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* After each device reset the MSI (4 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32l4xx.s" file, to
* configure the system clock before to branch to main program.
*
* This file configures the system clock as follows:
*=============================================================================
*-----------------------------------------------------------------------------
* System Clock source | MSI
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 4000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 4000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 1
*-----------------------------------------------------------------------------
* APB2 Prescaler | 1
*-----------------------------------------------------------------------------
* PLL_M | 1
*-----------------------------------------------------------------------------
* PLL_N | 8
*-----------------------------------------------------------------------------
* PLL_P | 7
*-----------------------------------------------------------------------------
* PLL_Q | 2
*-----------------------------------------------------------------------------
* PLL_R | 2
*-----------------------------------------------------------------------------
* PLLSAI1_P | NA
*-----------------------------------------------------------------------------
* PLLSAI1_Q | NA
*-----------------------------------------------------------------------------
* PLLSAI1_R | NA
*-----------------------------------------------------------------------------
* PLLSAI2_P | NA
*-----------------------------------------------------------------------------
* PLLSAI2_Q | NA
*-----------------------------------------------------------------------------
* PLLSAI2_R | NA
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Disabled
* SDIO and RNG clock |
*-----------------------------------------------------------------------------
*=============================================================================
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32l4xx_system
* @{
*/
/** @addtogroup STM32L4xx_System_Private_Includes
* @{
*/
#include "stm32l4xx.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (MSI_VALUE)
#define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @}
*/
/** @addtogroup STM32L4xx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32L4xx_System_Private_Defines
* @{
*/
/************************* Miscellaneous Configuration ************************/
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
/******************************************************************************/
/**
* @}
*/
/** @addtogroup STM32L4xx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32L4xx_System_Private_Variables
* @{
*/
/* The SystemCoreClock variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 4000000U;
const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
const uint32_t MSIRangeTable[12] = {100000U, 200000U, 400000U, 800000U, 1000000U, 2000000U, \
4000000U, 8000000U, 16000000U, 24000000U, 32000000U, 48000000U};
/**
* @}
*/
/** @addtogroup STM32L4xx_System_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32L4xx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system.
* @param None
* @retval None
*/
void SystemInit(void)
{
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set MSION bit */
RCC->CR |= RCC_CR_MSION;
/* Reset CFGR register */
RCC->CFGR = 0x00000000U;
/* Reset HSEON, CSSON , HSION, and PLLON bits */
RCC->CR &= 0xEAF6FFFFU;
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x00001000U;
/* Reset HSEBYP bit */
RCC->CR &= 0xFFFBFFFFU;
/* Disable all interrupts */
RCC->CIER = 0x00000000U;
/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
* or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) MSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value
* 4 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (***) HSE_VALUE is a constant defined in stm32l4xx_hal.h file (default value
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t tmp = 0U, msirange = 0U, pllvco = 0U, pllr = 2U, pllsource = 0U, pllm = 2U;
/* Get MSI Range frequency--------------------------------------------------*/
if((RCC->CR & RCC_CR_MSIRGSEL) == RESET)
{ /* MSISRANGE from RCC_CSR applies */
msirange = (RCC->CSR & RCC_CSR_MSISRANGE) >> 8U;
}
else
{ /* MSIRANGE from RCC_CR applies */
msirange = (RCC->CR & RCC_CR_MSIRANGE) >> 4U;
}
/*MSI frequency range in HZ*/
msirange = MSIRangeTable[msirange];
/* Get SYSCLK source -------------------------------------------------------*/
switch (RCC->CFGR & RCC_CFGR_SWS)
{
case 0x00: /* MSI used as system clock source */
SystemCoreClock = msirange;
break;
case 0x04: /* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x08: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x0C: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
SYSCLK = PLL_VCO / PLLR
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4U) + 1U ;
switch (pllsource)
{
case 0x02: /* HSI used as PLL clock source */
pllvco = (HSI_VALUE / pllm);
break;
case 0x03: /* HSE used as PLL clock source */
pllvco = (HSE_VALUE / pllm);
break;
default: /* MSI used as PLL clock source */
pllvco = (msirange / pllm);
break;
}
pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8U);
pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25U) + 1U) * 2U;
SystemCoreClock = pllvco/pllr;
break;
default:
SystemCoreClock = msirange;
break;
}
/* Compute HCLK clock frequency --------------------------------------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
/* HCLK clock frequency */
SystemCoreClock >>= tmp;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View file

@ -0,0 +1,11 @@
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef _ATCMD_CONFIG_PLATFORM_H_
#define _ATCMD_CONFIG_PLATFORM_H_
// AT uart
#define AT_UART_PORT 3
#endif

View file

@ -0,0 +1,40 @@
#include "hal/soc/soc.h"
#include <aos/kernel.h>
/* Logic partition on flash devices */
hal_logic_partition_t hal_partitions[HAL_PARTITION_MAX];
static void board_partition_init()
{
hal_partitions[HAL_PARTITION_APPLICATION].partition_owner = HAL_FLASH_EMBEDDED;
hal_partitions[HAL_PARTITION_APPLICATION].partition_description = "Application";
hal_partitions[HAL_PARTITION_APPLICATION].partition_start_addr = 0x08000000;
hal_partitions[HAL_PARTITION_APPLICATION].partition_length = 0x3C000; //240k bytes
hal_partitions[HAL_PARTITION_APPLICATION].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_owner = HAL_FLASH_EMBEDDED;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_description = "PARAMETER1";
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_start_addr = 0x0803C000;
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_length = 0x1000; // 4k bytes
hal_partitions[HAL_PARTITION_PARAMETER_1].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_owner = HAL_FLASH_EMBEDDED;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_description = "PARAMETER2";
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_start_addr = 0x0803D000;
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_length = 0x2000; //8k bytes
hal_partitions[HAL_PARTITION_PARAMETER_2].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN;
hal_partitions[HAL_PARTITION_PARAMETER_4].partition_owner = HAL_FLASH_EMBEDDED;
hal_partitions[HAL_PARTITION_PARAMETER_4].partition_description = "PARAMETER4";
hal_partitions[HAL_PARTITION_PARAMETER_4].partition_start_addr = 0x0803F000;
hal_partitions[HAL_PARTITION_PARAMETER_4].partition_length = 0x1000; //4k bytes
hal_partitions[HAL_PARTITION_PARAMETER_4].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN;
}
void board_init(void)
{
board_partition_init();
board_cli_init();
}

Some files were not shown because too many files have changed in this diff Show more