您的位置:首页 > 其它

GCC和IAR编译器内建函数以及C常用自定义函数

2017-07-31 10:24 423 查看
1 GCC内建函数

1.1 int __builtin_constant_p( exp )

GCC的内建函数 __builtin_constant_p 用于判断一个值是否为编译时常数,如果参数exp的值是常数,函数返回 1,否则返回 0。

弱函数

__attribute__((weak))  var_type function(var_type)

{

}

或者:

extern var_type function(var_type)  __attribute__((weak));

var_type function(var_type)

{

}

1.2 FreeRTOS自定义section

@flash.ld

SECTIONS

{

      […]

     .text :

     {

          […]

         . = ALIGN(4);

         PROVIDE (__core_initcall = .);

         KEEP(*(.core.initcall))

         PROVIDE (__core_initcall_end = .);

         . = ALIGN(4);

         PROVIDE (__module_initcall = .);

         KEEP(*(.module.initcall))

         PROVIDE (__module_initcall_end = .);

        . = ALIGN(4);

        PROVIDE (__late_initcall = .);

        KEEP(*(.late.initcall))

        PROVIDE (__late_initcall_end = .);

        . = ALIGN(4);

        PROVIDE (__atcmds_section = .);

        KEEP(*(.oem_atcmds))

        PROVIDE (__atcmds_section_end = .);

        […]

     }

     […]

}

@cutils.h

typedef void (*initcall_t)(void);

extern initcall_t __core_initcall[];

extern initcall_t __core_initcall_end[];

extern initcall_t __module_initcall[];

extern initcall_t __module_initcall_end[];

extern initcall_t __late_initcall[];

extern initcall_t __late_initcall_end[];

#if 1

#define core_initcall(fn)               \

    static initcall_t __initcall_##fn   \

__attribute__((used,section(".core.initcall"))) = fn

#define module_init(fn)                 \

    static initcall_t __initcall_##fn   \

__attribute__((used,section(".module.initcall"))) = fn

#define late_initcall(fn)               \

    static initcall_t __initcall_##fn   \

__attribute__((used,section(".late.initcall"))) = fn

#else

#define core_initcall(fn)               \

    void fn(void) __attribute__((unused))

#define module_init(fn)                 \

    void fn(void) __attribute__((unused))

#define late_initcall(fn)               \

    void fn(void) __attribute__((unused))

#endif

extern const atci_cmd_hdlr_item_t __atcmds_section[];

extern const atci_cmd_hdlr_item_t __atcmds_section_end[];

#if 1

#define DECLARE_AT_COMMAND(NAME, ROUTINE)                   \

    static const char __atcmd_label_##NAME[] = "AT+"#NAME;  \

static const atci_cmd_hdlr_item_t __atcmd_##NAME            \

__attribute__((used,section(".oem_atcmds"))) =              \

{                                                           \

    .command_head = __atcmd_label_##NAME,                   \

    .command_hdlr = ROUTINE,                                \

}

#else

#define DECLARE_AT_COMMAND(NAME, ROUTINE)           \

    atci_status_t (ROUTINE)(atci_parse_cmd_param_t *parse_cmd) __attribute__((unused))

#endif

@main.c

static void section_core_init(void)

{

    initcall_t *initcall;

    for (initcall = __core_initcall;

            initcall < __core_initcall_end;

            initcall++) {

        (*initcall)();

    }

}

static void section_module_init(void)

{

    initcall_t *initcall;

    for (initcall = __module_initcall;

            initcall < __module_initcall_end;

            initcall++) {

        (*initcall)();

    }

}

static void section_late_init(void)

{

    initcall_t *initcall;

    for (initcall = __late_initcall;

            initcall < __late_initcall_end;

            initcall++) {

        (*initcall)();

    }

}

static bool atcmds_section_cb(atci_parse_cmd_param_ex_t *parse_cmd)

{

    atci_cmd_hdlr_item_t *handler;

    for (handler = __atcmds_section;

            handler < __atcmds_section_end;

            handler++) {

        LOGE("command_head: %s; "

                "parse_cmd->string_ptr: %s, parse_cmd->hash_value1: 0x%08x, "

                "parse_cmd->hash_value2: 0x%08x\r\n",

                handler->command_head,

                parse_cmd->string_ptr, parse_cmd->hash_value1, parse_cmd->hash_value2);

        if (!strncmp((char *)parse_cmd->string_ptr,

                    handler->command_head,

                    strlen(handler->command_head))) {

            handler->command_hdlr((atci_parse_cmd_param_t*)parse_cmd);

            return true;

        }

    }

    return false;

}

2 IAR

2.1 URLs

IAR程序中获取堆指针与栈指针
http://blog.csdn.net/sunheshan/article/details/48548103
3 MCU链表操作头文件-porting from Linux

@ utils.h

#if !defined(__UTILS_H)

#define __UTILS_H

#ifdef __cplusplus

extern "C" {

#endif

#include <ctype.h>

#include <stdbool.h>

#include <stdint.h>

#include <stdio.h>

#include <string.h>

#ifndef offsetof

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#endif

#define container_of(ptr, type, member) ({          \

    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \

    (type *)( (char *)__mptr - offsetof(type,member) );})

struct list_head {

    struct list_head *next, *prev;

};

#define LIST_HEAD(name)     \

struct list_head name = {   \

    .next = &(name),        \

    .prev = &(name),        \

}

#define LEGACY_LIST_HEAD(type, name)    \

type name = {                           \

    .next = &(name),                    \

    .prev = &(name),                    \

}

#define list_empty(head) ((head) == (head)->next)

#define list_for_each(node, head) \

    for (node = (head)->next; node != (head); node = node->next)

#define list_for_each_safe(node, n, head)       \

    for (node = (head)->next, n = node->next;   \

         node != (head);                        \

         node = n, n = node->next)

#define list_init(head) do {    \

    (head)->next = (head);      \

    (head)->prev = (head);      \

} while (0)

#define list_add_head(node, head) do {  \

    (node)->next = (head)->next;        \

    (node)->prev = (head);              \

    (head)->next->prev = (node);        \

    (head)->next = (node);              \

} while (0)

#define list_add_tail(node, head) do {  \

    (node)->next = (head);              \

    (node)->prev = (head)->prev;        \

    (head)->prev->next = (node);        \

    (head)->prev = (node);              \

} while (0)

#define list_del(node) do {             \

    (node)->next->prev = (node)->prev;  \

    (node)->prev->next = (node)->next;  \

    (node)->next = NULL;                \

    (node)->prev = NULL;                \

} while (0)

#ifdef __cplusplus

}

#endif

#endif

4 AT Command Parser

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef int int32;

static char *at_tok_next_int(char *str, int32 *tok)

{

    char *p, *end;

    if (!str || !tok) {

        return NULL;

    }

    p = str;

    while (*p != '\0' && *p != '\r' && *p != '\n' && isspace(*p)) p++;

    if (*p == '\0') {

        goto err;

    }

    if (strchr(p, ',')) {

        end = strchr(p, ',');

        *end = '\0';

        end++;

    } else {

        end = p + strlen(p);

    }

    *tok = strtoul(p, NULL, 0);

    return end;

err:

    return NULL;

}

static char *at_tok_next_str(char *str, char *tok)

{

    char *p, *end;

    unsigned int i;

    if (!str || !tok) {

        return NULL;

    }

    p = str;

    while (*p != '\0' && *p != '\r' && *p != '\n' && isspace(*p)) p++;

    if (*p == '\0') {

        goto err;

    }

    if (strchr(p, ',')) {

        end = strchr(p, ',');

        *end = '\0';

        end++;

    } else {

        end = p + strlen(p);

    }

    strcpy(tok, p);

    for (i = strlen(tok); i >= 0; i--) {

        if (isalpha(tok[i]) || isdigit(tok[i])) {

            break;

        } else if (isspace(tok[i]) || tok[i] == '\r' || tok[i] == '\n') {

            tok[i] = '\0';

        }

    }

 

    return end;

err:

    return NULL;

}

int main(int argc, char **argv)

{

    char at[] = {"AT+TEST=5,1,HELLO\r\n"};

    int prx_len = strlen("AT+TEST=");

    char *p = at + prx_len;

    int v1;

    int v2;

    char v3[16];

    p = at_tok_next_int(p, &v1);        

    if (p) {

        p = at_tok_next_int(p, &v2);        

    }

    if (p) {

        p = at_tok_next_str(p, v3);        

    }

    fprintf(stdout, "%d %d %s\n", v1, v2, v3);

    return 0;
}

5 JSON

#define API(func) func

#define ACTION_SZ 64

#define AUTH_SZ 32

#define UUID_SZ 32

#define PARAMS_SZ 256

#define MSG_SZ 64

#define STATUS_SZ 32

#define RESULT_SZ 256

typedef unsigned int u32;

typedef struct req_arg {

    char action[ACTION_SZ];

    char auth[AUTH_SZ];

    char uuid[UUID_SZ];

    char params[PARAMS_SZ];

} req_arg_t;

typedef struct rsp_arg {

    char msg[MSG_SZ];

    char uuid[UUID_SZ];

    char status[STATUS_SZ];

    char result[RESULT_SZ];

} rsp_arg_t;

void API(u_json_clr_qm)(char *json)

{

    int i;

    for (i = 0; i < strlen(json); i++) {

        if (json[i] == '\"') {

            json[i] = ' ';

        }

    }

}

int API(u_json_get_value)(const char *json, int json_len, const char *key,

        char *value, int value_len)

{

    char *p, *p2, *end;

    unsigned int nleft = 0, nright = 0;

    unsigned int i, len;

    if (!json || !key || !value) {

        goto err;

    }

    p = strstr(json, key);

    if (!p) {

        printf("Oops\n");

        goto err;

    }

    p += strlen(key);

    while (*p != '\0' && *p != ':') p++;

    if (*p != ':') {

        printf("err1, invalid json string: %s\n", json);

        goto err;

    }

    p++;

    while (*p != '\0' && isspace(*p)) p++;

   

    //printf("DEBUG:%s-\n", p);

 

    if (*p == '{') {

        p++;

        end = p;

        

        while (*end != '\0' && *end != '}') end++;

        if (*end != '}') {

            printf("err2, invalid json string: %s\n", json);

            goto err;

        }

        

        p2 = p;

        // In 64bit machine, this will show a warning message,

        // because of sizeof(char *) = 8, but sizeof(u32) = 4

        //while ((u32)p2 != (u32)end) {

        while ((u32)p2 < (u32)end) {

            if (*p2 == '{') {

                nleft++;

            }

            p2++;

        }

        if (nleft > 0) {

            end++;

            while (*end != '\0') {

                if (*end == '}') {

                    nright++;

                }

                if (nleft == nright) {

                    break;

                }

                end++;

            }

        }

    } else {

        end = p;

        while (*end != '\0' && *end != ',' && *end != '}') end++;

        // TODO: Need check error?

    }

    len = (u32)(end - p);

    value_len = len < (value_len - 1) ? len : (value_len - 1);

    memcpy(value, p, value_len);

    value[value_len] = '\0';

    for (i = value_len; i >= 0; i--) {

        if (isalpha(value[i]) || isdigit(value[i])) {

            break;

        } else if (isspace(value[i])) {

            value[i] = '\0';

        }

    }

    return 0;

err:

    return -1;

}

6 Customized Print Function

#include <stdarg.h>

static int format_xxx_data(unsigned char *buf, unsigned int buf_len, const char *fmt,...)

{

    va_list ap;

    int n;

    if (NULL == buf) {

        return -1;

    }

    va_start(ap, fmt);

    n = vsnprintf(buf, buf_len, fmt, ap);

    va_end(ap);

    return n;

}

7 ringbuf(num_of_msgs是2的N次方,siz_of_msg > 0)

typedef struct {

    uint8_t *buf;

    uint16_t num_of_msgs;

    uint16_t siz_of_msg;

    uint32_t write_seq;

    uint32_t read_seq;

#define AVAIL_BIT 0x01

    EventGroupHandle_t event_group;

    SemaphoreHandle_t sem;

} ringbuf_t;

static bool ringbuf_popback(ringbuf_t *handle, void *msg)

{

    uint32_t offset;

    if (!handle || !msg) {

        return false;

    }

    if (NULL != handle->sem) {

        xSemaphoreTake(handle->sem, portMAX_DELAY);

    }

    if (handle->read_seq == handle->write_seq) {

        goto out;

    }

    offset = (handle->read_seq & (handle->num_of_msgs - 1)) * handle->siz_of_msg;

    memcpy(msg, &(handle->buf[offset]), handle->siz_of_msg);

    handle->read_seq++;

    if (NULL != handle->sem) {

        xSemaphoreGive(handle->sem);

    }

    return true;

out:

    if (NULL != handle->sem) {

        xSemaphoreGive(handle->sem);

    }

    return false;

}

static void ringbuf_push(ringbuf_t *handle, void *msg)

{

    uint32_t offset;

    if (!handle || !msg) {

        return;

    }

    if (NULL != handle->sem) {

        xSemaphoreTake(handle->sem, portMAX_DELAY);

    }

    offset = (handle->write_seq & (handle->num_of_msgs - 1)) * handle->siz_of_msg;

    memcpy(&(handle->buf[offset]), msg, handle->siz_of_msg);

    handle->write_seq++;

    if ((handle->write_seq - handle->read_seq) > handle->num_of_msgs) {

        handle->read_seq = handle->write_seq - handle->num_of_msgs;

    }

    if (NULL != handle->sem) {

        xSemaphoreGive(handle->sem);

    }

    xEventGroupSetBits(handle->event_group, AVAIL_BIT);

}

static bool ringbuf_empty(ringbuf_t *handle)

{

    bool ret = false;

    if (!handle) {

        return true;

    }

    if (NULL != handle->sem) {

        xSemaphoreTake(handle->sem, portMAX_DELAY);

    }

    if (handle->read_seq == handle->write_seq) {

        ret = true;

    }

    if (NULL != handle->sem) {

        xSemaphoreGive(handle->sem);

    }

    return ret;

}

static ringbuf_t *ringbuf_create(uint16_t num_of_msgs, uint16_t siz_of_msg)

{

    ringbuf_t *rb;

    rb = pvPortMalloc(sizeof(ringbuf_t));

    if (!rb) {

        goto out;

    }

    rb->num_of_msgs = num_of_msgs;

    rb->siz_of_msg = siz_of_msg;

    rb->buf = pvPortMalloc(num_of_msgs * siz_of_msg);

    if (!rb->buf) {

        goto free_rb;

    }

    rb->sem = xSemaphoreCreateBinary();

    if(!rb->sem) {

        goto free_buf;

    }

    xSemaphoreGive(rb->sem);

    rb->event_group = xEventGroupCreate();

    if (!rb->event_group) {

        goto del_sem;

    }

    return rb;

del_sem:

    vSemaphoreDelete(rb->sem);

    rb->sem = NULL;

free_buf:

    if (rb->buf) {

        vPortFree(rb->buf);

        rb->buf = NULL;

    }

free_rb:

    if (rb) {

        vPortFree(rb);

        rb = NULL;

    }

out:

    return NULL;

}

static void ringbuf_delete(ringbuf_t *handle)

{

    if (!handle) {

        return;

    }

    vEventGroupDelete(handle->event_group);

    vSemaphoreDelete(handle->sem);

    vPortFree(handle->buf);

    vPortFree(handle);

}

static void ringbuf_reset(ringbuf_t *handle)

{

    if (!handle) {

        return;

    }

    if (NULL != handle->sem) {

        xSemaphoreTake(handle->sem, portMAX_DELAY);

    }

    handle->read_seq = 0;

    handle->write_seq = 0;

    if (NULL != handle->sem) {

        xSemaphoreGive(handle->sem);

    }

}

static void ringbuf_wait(ringbuf_t *handle)

{

    if (!handle) {

        return;

    }

    xEventGroupWaitBits(handle->event_group,

            AVAIL_BIT,

            pdTRUE,

            pdFALSE,

            portMAX_DELAY);

}

8 Abbreviation

Linux ffs:find first bit set

Linux fls:find last (most-significant) set bit
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  System