回答----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 taskke_task_id_t app_task;/// Profile Task Number - if MSB bit set, Multi-Instantiated taskke_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 Numberke_task_id_t task;/// Profile Task Identifierke_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 tasksfor(i = 0; i < BLE_NB_PROFILES ; i++){// check if profile identifier is knownif(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 environmentprf_env_t prf_env;/// Service Start Handleuint16_t shdl;/// To store the DB max number of attributesuint8_t max_nb_att;/// On-going operationstruct ke_msg *operation;/// Cursor on connection used to notify peer devicesuint8_t cursor;/// CCC handle index, used during notification/indication busy stateuint8_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_REQstruct custs1_env_tag *custs1_env = PRF_ENV_GET(CUSTS1, custs1);struct custs1_env_tag
{/// profile environmentprf_env_t prf_env;/// Service Start Handleuint16_t shdl;/// To store the DB max number of attributesuint8_t max_nb_att;/// On-going operationstruct ke_msg *operation;/// Cursor on connection used to notify peer devicesuint8_t cursor;/// CCC handle index, used during notification/indication busy stateuint8_t ccc_idx;struct co_list values;/// CUSTS1 task stateke_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 taskke_task_id_t app_task;/// Profile Task Number - if MSB bit set, Multi-Instantiated taskke_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 taskke_task_id_t app_task;/// Profile Task Number - if MSB bit set, Multi-Instantiated taskke_task_id_t prf_task;
} prf_env_t;struct custs1_env_tag
{/// profile environmentprf_env_t prf_env;/// Service Start Handleint shdl;/// To store the DB max number of attributesint max_nb_att;/// On-going operationstruct ke_msg *operation;/// Cursor on connection used to notify peer devicesint cursor;/// CCC handle index, used during notification/indication busy stateint 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;
}
看上去是正常的 分配内存少一点也没有关系