基于RTT压缩包C基础-不明白的接口PRF_ENV_GET __attribute__

这篇博客探讨了C语言中结构体指针的使用,特别是通过宏定义PRF_ENV_GET进行类型转换和内存访问的安全性。文章分析了一个函数PRF_ENV_GET如何获取特定任务环境的指针,并且讨论了当指针类型比实际内存大小更大时是否安全。作者通过示例代码展示了指针分配和内存银行的概念,并进行了实际测试以验证其行为。博客还提到了消息发送和回调函数中的参数处理,以及可能涉及的内存操作。
摘要由CSDN通过智能技术生成

回答----https://blog.csdn.net/weixin_42381351/article/details/115524780?spm=1001.2014.3001.5501

用户APP里面 函数     struct custs1_env_tag *custs1_env = PRF_ENV_GET(CUSTS1, custs1);

这个是一个指针 分配内存 但是右边是强转的 实际上右边结构体要小呀 安不安全????

 

 


typedef uint16_t ke_task_id_t;

typedef struct prf_env
{
    /// Application Task Number - if MSB bit set, Multi-Instantiated task
    ke_task_id_t app_task;
    /// Profile Task  Number    - if MSB bit set, Multi-Instantiated task
    ke_task_id_t prf_task;
} prf_env_t;

//1----这是一个结构体








#define BLE_NB_PROFILES          32

/// Profile task environment variable definition to dynamically allocate a Task.
struct prf_task_env
{
    /// Profile Task description
    //struct ke_task_desc desc;
    /// pointer to the allocated memory used by profile during runtime.
    prf_env_t*          env;
    /// Profile Task Number
    ke_task_id_t        task;
    /// Profile Task Identifier
    ke_task_id_t        id;
};

/// Profile Manager environment structure
struct prf_env_tag
{
    /// Array of profile tasks that can be managed by Profile manager.
    struct prf_task_env prf[BLE_NB_PROFILES];
};

struct prf_env_tag prf_env __attribute__((section("retention_mem_area0"),zero_init));




prf_env_t* prf_env_get(uint16_t prf_id)
{
    prf_env_t* env = NULL;
    uint8_t i;
    // find if profile present in profile tasks
    for(i = 0; i < BLE_NB_PROFILES ; i++)
    {
        // check if profile identifier is known
        if(prf_env.prf[i].id == prf_id)
        {
            env = prf_env.prf[i].env;
            break;
        }
    }

    return env;
}

    prf_env_t tast_data = {0XAA,0XBB};
void my_init(void)
{
    prf_env.prf[20].id = 0x01;//  TASK_ID_CUSTS1; 假设数组中的20号是内存根源

    prf_env.prf[20].env = &tast_data;
}
//2----这是一个内存银行 最核心的其实是 prf_env_t*          env;它只是地址






    
#define PRF_ENV_GET(prf_id, type) \
        ((struct type ## _env_tag *)prf_env_get((TASK_ID_##prf_id)))
        
/*       
struct custs1_env_tag *custs1_env = PRF_ENV_GET(CUSTS1, custs1);
也就是 
struct custs1_env_tag *custs1_env = PRF_ENV_GET(CUSTS1, custs1);
                                  = (struct custs1_env_tag *)prf_env_get(TASK_ID_CUSTS1)
    1---custs1_env_tag  
    2---TASK_ID_CUSTS1       TASK_ID_CUSTS1       = 0xFD, // Custom1 Task
*/  

        
#define       TASK_ID_CUSTS1     0x01 
struct custs1_env_tag
{
    /// profile environment
    prf_env_t prf_env;
    /// Service Start Handle
    uint16_t shdl;
    /// To store the DB max number of attributes
    uint8_t max_nb_att;
    /// On-going operation
    struct ke_msg *operation;

    /// Cursor on connection used to notify peer devices
    uint8_t cursor;
    /// CCC handle index, used during notification/indication busy state
    uint8_t ccc_idx;
};        
static int custs1_val_ntf_req_handler(void)
{
    struct custs1_env_tag *custs1_env = PRF_ENV_GET(CUSTS1, custs1);

    //custs1_env->operation = ke_param2msg(param);
    custs1_env->cursor = 10;

    //ke_free(custs1_env->operation);
    custs1_env->operation = NULL;
}

//3----
//struct custs1_env_tag *custs1_env = PRF_ENV_GET(CUSTS1, custs1);
//这句话终于可以分析了 它是 一个指针分配内存 而右边不是一个数组中死死的内存 是一个提前malloc的内存
//好像是左边指针比较大 右边内存比较小啊  安全吗????

struct custs1_env_tag2
{
 uint8_t cursor;
 uint8_t ccc_idx;
};

struct custs1_env_tag2 *custs1_env2;
uint8_t abc=3;
int main(void)
{
    my_init();
    custs1_val_ntf_req_handler();
 
    custs1_env2 = (struct custs1_env_tag2 *)&abc;
    custs1_env2->ccc_idx=1;
    custs1_env2->cursor=2;
    return 0;
}

可以debug看的 正常

自己测试的 也没有崩溃

 

 

 

+++++++++++++++++++++++++继续问题++++++++++++++++

快要吐血 发个抖音吧 这个问题真不不理解 在表达一次

 

发消息 

void user_svc1_accel_X_send_ntf()
    struct custs1_val_ntf_ind_req* req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_NTF_REQ,                   //Message id

然后执行回调函数

static int custs1_val_ntf_req_handler(ke_msg_id_t const msgid,
    struct custs1_env_tag *custs1_env = PRF_ENV_GET(CUSTS1, custs1);
    custs1_env->operation = ke_param2msg(param);

已经明白了 参数 是req过来的  这个 ke_param2msg 不懂

 

它是修改指针的指向的 从头部修改到最后的U32 但是完全不相干啊

 

 

 

++++++再次描述一下++++

CUSTS1_VAL_NTF_REQ

struct custs1_env_tag *custs1_env = PRF_ENV_GET(CUSTS1, custs1);
    
struct custs1_env_tag
{
    /// profile environment
    prf_env_t prf_env;
    /// Service Start Handle
    uint16_t shdl;
    /// To store the DB max number of attributes
    uint8_t max_nb_att;
    /// On-going operation
    struct ke_msg *operation;
    /// Cursor on connection used to notify peer devices
    uint8_t cursor;
    /// CCC handle index, used during notification/indication busy state
    uint8_t ccc_idx;
    struct co_list values;
    /// CUSTS1 task state
    ke_state_t state[CUSTS1_IDX_MAX];
};
#define PRF_ENV_GET(prf_id, type) \
        ((struct type ## _env_tag *)prf_env_get((TASK_ID_##prf_id)))
 ((struct custs1_env_tag *)prf_env_get((TASK_ID_CUSTS1)))
 
prf_env_t* prf_env_get(uint16_t prf_id)
 
 /// Profile Environment Data
typedef struct prf_env
{
    /// Application Task Number - if MSB bit set, Multi-Instantiated task
    ke_task_id_t app_task;
    /// Profile Task  Number    - if MSB bit set, Multi-Instantiated task
    ke_task_id_t prf_task;
} prf_env_t;

 

 

++++++基于RTT自己测试一下 分配小内存看看+++++


#define      ke_task_id_t   int
#define      TASK_ID_CUSTS1 11
 /// Profile Environment Data
typedef struct prf_env
{
    /// Application Task Number - if MSB bit set, Multi-Instantiated task
    ke_task_id_t app_task;
    /// Profile Task  Number    - if MSB bit set, Multi-Instantiated task
    ke_task_id_t prf_task;
} prf_env_t;
    
struct custs1_env_tag
{
    /// profile environment
    prf_env_t prf_env;
    /// Service Start Handle
    int shdl;
    /// To store the DB max number of attributes
    int max_nb_att;
    /// On-going operation
    struct ke_msg *operation;
    /// Cursor on connection used to notify peer devices
    int cursor;
    /// CCC handle index, used during notification/indication busy state
    int ccc_idx;

};

prf_env_t data __attribute__((at(0X20000100))) ={1,2} ;
prf_env_t* prf_env_get(uint16_t prf_id)
{
 // static prf_env_t data={1,2};
  return &data;
}

#define PRF_ENV_GET(prf_id, type) \
        ((struct type ## _env_tag *)prf_env_get((TASK_ID_##prf_id)))
// ((struct custs1_env_tag *)prf_env_get((TASK_ID_CUSTS1)))
 
int main(void)
{
    struct custs1_env_tag *custs1_env = PRF_ENV_GET(CUSTS1, custs1);
    custs1_env->cursor=5;
    custs1_env->ccc_idx=6;

    return 0;
}

看上去是正常的 分配内存少一点也没有关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值