回答----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;
}
看上去是正常的 分配内存少一点也没有关系