fix(atomic): Remove GNUC extension syntax.

Fixes compilation errors caused by GNUC extension syntax(Fully adopted C99 standard).
Temporary removal tools(Function incomplete).
This commit is contained in:
MacRsh
2024-07-25 02:01:46 +08:00
parent 4ac318667b
commit ba3f400524
8 changed files with 55 additions and 433 deletions

View File

@@ -46,11 +46,11 @@ BreakStringLiterals: true
ColumnLimit: 100
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<std.*>'
- Regex: '.*'
Priority: 1
- Regex: '^<.*>'
Priority: 2
- Regex: '.*'
- Regex: '^<std.*>'
Priority: 3
IndentCaseBlocks: false
IndentCaseLabels: true

View File

@@ -9,7 +9,7 @@
#ifndef __MR_ATOMIC_H__
#define __MR_ATOMIC_H__
#include <include/mr_def.h>
#include <include/mr_service.h>
#ifdef __cplusplus
extern "C" {
@@ -20,26 +20,25 @@ extern "C" {
* @{
*/
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
#if defined(__CC_ARM) || defined(__GNUC__) || defined(__clang__)
#define mr_atomic_load(_ptr) \
((typeof(*(_ptr)))__atomic_load_n((_ptr), __ATOMIC_SEQ_CST))
(__atomic_load_n((_ptr), __ATOMIC_SEQ_CST))
#define mr_atomic_store(_ptr, _var) \
(__atomic_store_n((_ptr), (_var), __ATOMIC_SEQ_CST))
#define mr_atomic_fetch_add(_ptr, _var) \
((typeof(*(_ptr)))__atomic_fetch_add((_ptr), (_var), __ATOMIC_SEQ_CST))
(__atomic_fetch_add((_ptr), (_var), __ATOMIC_SEQ_CST))
#define mr_atomic_fetch_sub(_ptr, _var) \
((typeof(*(_ptr)))__atomic_fetch_sub((_ptr), (_var), __ATOMIC_SEQ_CST))
(__atomic_fetch_sub((_ptr), (_var), __ATOMIC_SEQ_CST))
#define mr_atomic_fetch_and(_ptr, _var) \
((typeof(*(_ptr)))__atomic_fetch_and((_ptr), (_var), __ATOMIC_SEQ_CST))
(__atomic_fetch_and((_ptr), (_var), __ATOMIC_SEQ_CST))
#define mr_atomic_fetch_or(_ptr, _var) \
((typeof(*(_ptr)))__atomic_fetch_or((_ptr), (_var), __ATOMIC_SEQ_CST))
(__atomic_fetch_or((_ptr), (_var), __ATOMIC_SEQ_CST))
#define mr_atomic_fetch_xor(_ptr, _var) \
((typeof(*(_ptr)))__atomic_fetch_xor((_ptr), (_var), __ATOMIC_SEQ_CST))
(__atomic_fetch_xor((_ptr), (_var), __ATOMIC_SEQ_CST))
#define mr_atomic_exchange(_ptr, _var) \
((typeof(*(_ptr)))__atomic_exchange_n((_ptr), (_var), __ATOMIC_SEQ_CST))
(__atomic_exchange_n((_ptr), (_var), __ATOMIC_SEQ_CST))
#define mr_atomic_compare_exchange_strong(_ptr, _old, _new) \
((bool)__atomic_compare_exchange_n((_ptr), (_old), (_new), 0, __ATOMIC_SEQ_CST, \
__ATOMIC_SEQ_CST))
(__atomic_compare_exchange_n((_ptr), (_old), (_new), 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
#else
/**
* @brief This macro function loads the value of the atomic variable.
@@ -54,13 +53,13 @@ MR_INLINE mr_atomic_t mr_atomic_load(volatile mr_atomic_t *ptr)
size_t mask;
/* Disable interrupt */
mask = mr_interrupt_disable();
mask = mr_irq_disable();
/* Read value */
tmp = *(mr_atomic_t *)ptr;
/* Enable interrupt */
mr_interrupt_enable(mask);
mr_irq_enable(mask);
return tmp;
}
@@ -75,13 +74,13 @@ MR_INLINE void mr_atomic_store(volatile mr_atomic_t *ptr, mr_atomic_t val)
size_t mask;
/* Disable interrupt */
mask = mr_interrupt_disable();
mask = mr_irq_disable();
/* Write value */
*ptr = val;
/* Enable interrupt */
mr_interrupt_enable(mask);
mr_irq_enable(mask);
}
/**
@@ -98,14 +97,14 @@ MR_INLINE mr_atomic_t mr_atomic_fetch_add(volatile mr_atomic_t *ptr, mr_atomic_t
size_t mask;
/* Disable interrupt */
mask = mr_interrupt_disable();
mask = mr_irq_disable();
/* Read value and add */
tmp = *ptr;
*ptr += val;
/* Enable interrupt */
mr_interrupt_enable(mask);
mr_irq_enable(mask);
return tmp;
}
@@ -123,14 +122,14 @@ MR_INLINE mr_atomic_t mr_atomic_fetch_sub(volatile mr_atomic_t *ptr, mr_atomic_t
size_t mask;
/* Disable interrupt */
mask = mr_interrupt_disable();
mask = mr_irq_disable();
/* Read value and sub */
tmp = *ptr;
*ptr -= val;
/* Enable interrupt */
mr_interrupt_enable(mask);
mr_irq_enable(mask);
return tmp;
}
@@ -148,14 +147,14 @@ MR_INLINE mr_atomic_t mr_atomic_fetch_and(volatile mr_atomic_t *ptr, mr_atomic_t
size_t mask;
/* Disable interrupt */
mask = mr_interrupt_disable();
mask = mr_irq_disable();
/* Read value and and */
tmp = *ptr;
*ptr &= val;
/* Enable interrupt */
mr_interrupt_enable(mask);
mr_irq_enable(mask);
return tmp;
}
@@ -173,14 +172,14 @@ MR_INLINE mr_atomic_t mr_atomic_fetch_or(volatile mr_atomic_t *ptr, mr_atomic_t
size_t mask;
/* Disable interrupt */
mask = mr_interrupt_disable();
mask = mr_irq_disable();
/* Read value and or */
tmp = *ptr;
*ptr |= val;
/* Enable interrupt */
mr_interrupt_enable(mask);
mr_irq_enable(mask);
return tmp;
}
@@ -198,14 +197,14 @@ MR_INLINE mr_atomic_t mr_atomic_fetch_xor(volatile mr_atomic_t *ptr, mr_atomic_t
size_t mask;
/* Disable interrupt */
mask = mr_interrupt_disable();
mask = mr_irq_disable();
/* Read value and xor */
tmp = *ptr;
*ptr ^= val;
/* Enable interrupt */
mr_interrupt_enable(mask);
mr_irq_enable(mask);
return tmp;
}
@@ -223,14 +222,14 @@ MR_INLINE mr_atomic_t mr_atomic_exchange(volatile mr_atomic_t *ptr, mr_atomic_t
size_t mask;
/* Disable interrupt */
mask = mr_interrupt_disable();
mask = mr_irq_disable();
/* Read value and exchange */
tmp = *ptr;
*ptr = val;
/* Enable interrupt */
mr_interrupt_enable(mask);
mr_irq_enable(mask);
return tmp;
}
@@ -251,23 +250,23 @@ MR_INLINE bool mr_atomic_compare_exchange_strong(volatile mr_atomic_t *ptr, mr_a
bool ret;
/* Disable interrupt */
mask = mr_interrupt_disable();
mask = mr_irq_disable();
/* Compare and exchange */
if (*ptr == *old)
{
*ptr = new;
ret = 1;
ret = true;
} else
{
ret = 0;
ret = false;
}
/* Enable interrupt */
mr_interrupt_enable(mask);
return tmp;
mr_irq_enable(mask);
return ret;
}
#endif /* defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM) */
#endif /* defined(__CC_ARM) || defined(__GNUC__) || defined(__clang__) */
/** @} */

View File

@@ -5,7 +5,7 @@
extern "C" {
#endif /* __cplusplus */
#define MR_CFG_HEAP_SIZE 8192
#define MR_CFG_HEAP_SIZE 4096
#ifdef __cplusplus
}

View File

@@ -10,13 +10,12 @@
#ifndef __MR_DEF_H__
#define __MR_DEF_H__
#include <include/mr_config.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <include/mr_config.h>
#include <string.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
@@ -36,7 +35,7 @@ extern "C" {
* @{
*/
#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM)
#if defined(__CC_ARM) || defined(__GNUC__) || defined(__clang__)
#define MR_SECTION(x) __attribute__((section(x)))
#define MR_UNUSED __attribute__((unused))
#define MR_USED __attribute__((used))
@@ -54,7 +53,7 @@ extern "C" {
#define MR_USED __attribute__((used))
#define MR_WEAK __attribute__((weak))
#define MR_INLINE static __inline
#endif /* __GNUC__ */
#endif /* defined(__CC_ARM) || defined(__GNUC__) */
/** @} */
@@ -213,7 +212,7 @@ typedef struct mr_class
void *privdata; /**< Private data */
size_t privsize; /**< Private data size */
mr_ref_t refcount; /**< Reference count */
void (*release)(struct mr_class *); /**< Release function */
void (*release)(struct mr_class *class); /**< Release function */
void *methods; /**< Methods */
} mr_class_t;

View File

@@ -9,6 +9,8 @@
#ifndef __MR_SERVICE_H__
#define __MR_SERVICE_H__
#include <include/mr_def.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -76,38 +78,32 @@ extern "C" {
/**
* @brief This macro function gets the maximum of two values.
*
* @param _type The type of the value.
* @param _a The first value.
* @param _b The second value.
*
* @return The maximum of the two values.
*/
#define MR_MAX(_type, _a, _b) \
((_type){(_a)} > (_type){(_b)} ? (_type){(_a)} : (_type){(_b)})
#define MR_MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))
/**
* @brief This macro function gets the minimum of two values.
*
* @param _type The type of the value.
* @param _a The first value.
* @param _b The second value.
*
* @return The minimum of the two values.
*/
#define MR_MIN(_type, _a, _b) \
((_type){(_a)} < (_type){(_b)} ? (_type){(_a)} : (_type){(_b)})
#define MR_MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
/**
* @brief This macro function ensures that a value is within a specified range.
*
* @param _value The value.
* @param _min The minimum value.
* @param _max The maximum value.
*
* @return The value within the specified range.
*/
#define MR_CLAMP(_type, _value, _min, _max) \
(MR_MAX(_type, MR_MIN(_type, _value, _max), _min))
#define MR_CLAMP(_value, _min, _max) (MR_MAX(MR_MIN((_value), (_max)), (_min)))
/**
* @brief This macro function swaps two values.

View File

@@ -134,7 +134,7 @@ int mr_class_add(mr_class_t *class, mr_class_t *parent)
mr_spin_lock(&parent->lock);
/* Check if the same name class already exists */
if (__class_find(parent, class->name) == NULL)
if (__class_find(parent, class->name) != NULL)
{
ret = MR_EEXIST;
goto _exit;
@@ -145,7 +145,15 @@ int mr_class_add(mr_class_t *class, mr_class_t *parent)
{
class->privsize = parent->privsize;
class->methods = parent->methods;
if (class->privsize > 0)
{
class->privdata = mr_malloc(class->privsize);
if (class->privdata == NULL)
{
ret = MR_ENOMEM;
goto _exit;
}
}
/* Child class's private data must be larger than parent's */
} else if (class->privsize < parent->privsize)
{
@@ -428,8 +436,6 @@ mr_class_t *mr_class_find(mr_class_t *parent, const char *path)
{
return mr_class_find(class, slash + 1);
}
/* Return the found class */
return class;
}
@@ -467,22 +473,9 @@ bool mr_class_is_subclass(mr_class_t *class, mr_class_t *base)
*/
void *mr_class_get_privdata(mr_class_t *class)
{
uint32_t mask;
MR_ASSERT(class != NULL);
/* Lock the class */
mask = mr_spin_lock_irqsave(&class->lock);
/* Allocate the private data */
if ((class->privdata == NULL) && (class->privsize > 0))
{
class->privdata = mr_malloc(class->privsize);
memset(class->privdata, 0, class->privsize);
}
/* Unlock the class */
mr_spin_unlock_irqrestore(&class->lock, mask);
/* Get the private data */
return class->privdata;
}

View File

@@ -1,300 +0,0 @@
#!/usr/bin/env python
"""
@copyright (c) 2023-2024, MR Development Team
@license SPDX-License-Identifier: Apache-2.0
@date 2023-12-17 MacRsh First version
"""
import os
import logging
import argparse
import subprocess
from pathlib import Path
try:
from lxml import etree
except ImportError:
subprocess.run(['pip', 'install', 'lxml'], check=True)
from lxml import etree
try:
from kconfiglib import Kconfig
except ImportError:
subprocess.run(['pip', 'install', 'kconfiglib'], check=True)
try:
import curses
except ImportError:
subprocess.run(['pip', 'install', 'windows-curses'], check=True)
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
class MDK5:
def __init__(self, mdk_path):
self.path, self.file = self._find_uvprojx_file(mdk_path)
if self.file:
self.exist = True
self.tree = etree.parse(self.file)
self.root = self.tree.getroot()
else:
self.exist = False
@staticmethod
def _find_uvprojx_file(mdk_path):
for root, dirs, files in os.walk(mdk_path):
for file in files:
if file.endswith('.uvprojx'):
return Path(root), Path(root) / file
return None, None
def add_include_path(self, path):
path = Path(path).relative_to(self.path).as_posix()
inc_path = self.tree.xpath("//Cads/VariousControls/IncludePath")[0]
exist_paths = inc_path.text.split(';')
if path not in exist_paths:
inc_path.text += f";{path}"
logging.info(f"include {path}")
def add_file_to_group(self, name, file):
file = Path(file).relative_to(self.path).as_posix()
groups_node = self.tree.find('//Groups')
group_node = groups_node.find(f"./Group[GroupName='{name}']")
if group_node is None:
group_node = etree.SubElement(groups_node, "Group")
group_name_node = etree.SubElement(group_node, "GroupName")
group_name_node.text = name
files_node = group_node.find("Files")
if files_node is None:
files_node = etree.SubElement(group_node, "Files")
# Add file
file_node = files_node.find(
f"./File[FileName='{os.path.basename(file)}']")
if file_node is None:
file_node = etree.SubElement(files_node, "File")
file_name_node = file_node.find(f"./FileName")
if file_name_node is None:
file_name_node = etree.SubElement(file_node, "FileName")
file_type_node = file_node.find(f"./FileType")
if file_type_node is None:
file_type_node = etree.SubElement(file_node, "FileType")
file_path_node = file_node.find(f"./FilePath")
if file_path_node is None:
file_path_node = etree.SubElement(file_node, "FilePath")
file_name_node.text = os.path.basename(file)
file_path_node.text = file
file_type_map = {
'.c': '1',
'.s': '2',
'.o': '3',
'.lib': '4',
'.h': '5',
'.cpp': '8'
}
file_extension = os.path.splitext(file_name_node.text)[1]
file_type = file_type_map.get(file_extension, '9')
file_type_node.text = file_type
logging.info(f"=> {file}")
def add_file(self, file):
group_name = Path(file).relative_to(
self.path).parent.as_posix().replace('../', '')
file = Path(file).relative_to(self.path).as_posix()
self.add_file_to_group(group_name, file)
def add_files(self, files):
for file in files:
self.add_file(file)
def use_gnu(self, enable=True):
ac6_node = self.tree.find('//Target/uAC6')
if ac6_node is None:
logging.error("Config GNU failed")
return
if ac6_node.text == '0':
gnu_node = self.tree.find('//Cads/uGnu')
gnu_text = '1' if enable else '0'
else:
gnu_node = self.tree.find('//Cads/v6Lang')
gnu_text = '4' if enable else '3'
if gnu_node is not None:
if gnu_node.text != gnu_text:
gnu_node.text = gnu_text
logging.info("Config GNU successfully")
def save(self):
self.tree.write(self.file, pretty_print=True, encoding="utf-8",
xml_declaration=True)
logging.info("Build project successfully")
class Eclipse:
def __init__(self, eclipse_path):
self.path, self.file = self._find_cproject_file(eclipse_path)
if self.file:
self.exist = True
self.tree = etree.parse(self.file)
self.root = self.tree.getroot()
else:
self.exist = False
@staticmethod
def _find_cproject_file(eclipse_path):
for root, dirs, files in os.walk(eclipse_path):
for file in files:
if file.endswith('.cproject'):
return Path(root), Path(root) / file
return None, None
def use_auto_init(self):
ld_file = self._find_ld_file(self.path)
if ld_file:
with ld_file.open() as fr:
content = fr.read()
pos = content.find('.text :')
if pos == -1:
return
if '/* mr-library */' not in content:
pos_offset = content[pos:].find('}')
if pos_offset == -1:
return
pos += pos_offset
link_config = """
/* mr-library */
. = ALIGN(4);
KEEP(*(SORT(mr_auto_init.*)))
KEEP(*(SORT(mr_msh_cmd.*)))
. = ALIGN(4);
"""
with ld_file.open('w') as fw:
fw.write(content[:pos] + link_config + content[pos:])
logging.info("Config auto-init successfully")
else:
logging.warning("Config auto-init failed, '.ld' not found")
@staticmethod
def _find_ld_file(path):
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith(".ld"):
return Path(root) / file
return None
def add_include_path(self, path):
path = Path(path).relative_to(self.path).as_posix()
path_nodes = self.tree.findall(".//option[@valueType='includePath']")
for path_node in path_nodes:
path_node_id = path_node.get('id')
if 'c.compiler' in path_node_id and 'include' in path_node_id:
option = path_node.find(f".//listOptionValue[@value='{path}']")
if option is None:
etree.SubElement(path_node, "listOptionValue",
builtIn="false", value=path)
logging.info(f"=> {path}")
break
def save(self):
self.tree.write(self.file, pretty_print=True, encoding="utf-8",
xml_declaration=True)
logging.info("Build project successfully")
class MrLib:
def __init__(self):
self.path = Path.cwd()
self.c_files = list(self.path.rglob('*.c'))
self.h_files = list(self.path.rglob('*.h'))
self.proj_path = self.path.parent
def show_logo():
logo = """
__ __ _ _ _
| \/ | _ __ | | (_) | |__ _ __ __ _ _ __ _ _
| |\/| | | '__| _____ | | | | | '_ \ | '__| / _` | | '__| | | | |
| | | | | | |_____| | | | | | |_) | | | | (_| | | | | |_| |
|_| |_| |_| |_| |_| |_.__/ |_| \__,_| |_| \__, |
|___/"""
print(logo)
def show_license():
license_file = Path(__file__).parent / "LICENSE"
with license_file.open() as f:
print(f.read())
def build_mdk(proj_path, include_path, c_files):
mdk_proj = MDK5(proj_path)
mdk_proj.add_include_path(include_path)
mdk_proj.add_files(c_files)
mdk_proj.use_gnu(True)
mdk_proj.save()
def build_eclipse(proj_path, path):
eclipse_proj = Eclipse(proj_path)
eclipse_proj.add_include_path(path)
eclipse_proj.use_auto_init()
eclipse_proj.save()
def menuconfig():
devnull_path = os.devnull if os.name == 'nt' else '/dev/null'
try:
with open(devnull_path, 'w') as devnull:
subprocess.run(["menuconfig"], stdout=devnull, stderr=devnull,
check=True)
except subprocess.CalledProcessError:
logging.error("Config menuconfig failed")
exit(1)
try:
subprocess.run(["python", "tools/kconfig.py"], check=True)
except subprocess.CalledProcessError:
logging.error("Config menuconfig failed, 'kconfig.py' not found")
exit(1)
def build():
mr_lib = MrLib()
mdk5 = MDK5(mr_lib.proj_path)
if mdk5.exist:
build_mdk(mr_lib.proj_path, mr_lib.path, mr_lib.c_files)
else:
eclipse = Eclipse(mr_lib.proj_path)
if eclipse.exist:
build_eclipse(mr_lib.proj_path, mr_lib.path)
else:
logging.error("Found project(MDK5 or Eclipse) failed")
exit(1)
if __name__ == '__main__':
show_logo()
parser = argparse.ArgumentParser()
parser.add_argument("-m", "--menuconfig", action="store_true",
help="Run menuconfig")
parser.add_argument("-b", "--build", action="store_true",
help="Build project")
parser.add_argument("-l", "--license", action="store_true",
help="Show license")
parser.add_argument("-g", "--generate",
action="store_true",
help="Generate library include file")
args = parser.parse_args()
if args.build:
build()
if args.menuconfig:
menuconfig()
if args.license:
show_license()
if args.generate:
mr = MrLib()

View File

@@ -1,65 +0,0 @@
#!/usr/bin/env python
"""
@copyright (c) 2023-2024, MR Development Team
@license SPDX-License-Identifier: Apache-2.0
@date 2023-12-17 MacRsh First version
"""
import re
import logging
from kconfiglib import Kconfig
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
def generate_config_file(kconfig_file, config_in, config_out, header_out):
kconf = Kconfig(kconfig_file, warn=False, warn_to_stderr=False)
# Load config
kconf.load_config(config_in)
kconf.write_config(config_out)
kconf.write_autoconf(header_out)
with open(header_out, 'r+') as header_file:
content = header_file.read()
header_file.truncate(0)
header_file.seek(0)
# Remove CONFIG_ and MR_USE_XXX following number
content = content.replace("#define CONFIG_", "#define ")
content = re.sub(r'#define MR_USE_(\w+) (\d+)', r'#define MR_USE_\1', content)
# Add the micro
header_file.write("#ifndef __MR_CONFIG_H__\n")
header_file.write("#define __MR_CONFIG_H__\n\n")
header_file.write("#ifdef __cplusplus\n")
header_file.write("extern \"C\" {\n")
header_file.write("#endif /* __cplusplus */\n\n")
# Write back the original data
header_file.write(content)
# Add the micro
header_file.write("\n#ifdef __cplusplus\n")
header_file.write("}\n")
header_file.write("#endif /* __cplusplus */\n\n")
header_file.write("#endif /* __MR_CONFIG_H__ */\n")
header_file.close()
logging.info("Build mr-library config file successfully")
def main():
kconfig_file = 'Kconfig'
config_in = '.config'
config_out = '.config'
header_out = 'include/mr_config.h'
generate_config_file(kconfig_file, config_in, config_out, header_out)
if __name__ == "__main__":
main()