* @brief Creating a messagequeue object. * * @note For the messagequeue object, its memory space is allocated automatically. * By contrast, the rt_mq_init() function will initialize a static messagequeue object. * * @see rt_mq_init() * * @param name is a pointer that given to the messagequeue. * * @param msg_size is the maximum length of a message in the messag
| 3232 | * @warning This function can NOT be called in interrupt context. You can use macor RT_DEBUG_NOT_IN_INTERRUPT to check it. |
| 3233 | */ |
| 3234 | rt_mq_t rt_mq_create(const char *name, |
| 3235 | rt_size_t msg_size, |
| 3236 | rt_size_t max_msgs, |
| 3237 | rt_uint8_t flag) |
| 3238 | { |
| 3239 | struct rt_messagequeue *mq; |
| 3240 | struct rt_mq_message *head; |
| 3241 | rt_base_t temp; |
| 3242 | register rt_size_t msg_align_size; |
| 3243 | |
| 3244 | RT_ASSERT((flag == RT_IPC_FLAG_FIFO) || (flag == RT_IPC_FLAG_PRIO)); |
| 3245 | |
| 3246 | RT_DEBUG_NOT_IN_INTERRUPT; |
| 3247 | |
| 3248 | /* allocate object */ |
| 3249 | mq = (rt_mq_t)rt_object_allocate(RT_Object_Class_MessageQueue, name); |
| 3250 | if (mq == RT_NULL) |
| 3251 | return mq; |
| 3252 | |
| 3253 | /* set parent */ |
| 3254 | mq->parent.parent.flag = flag; |
| 3255 | |
| 3256 | /* initialize ipc object */ |
| 3257 | _ipc_object_init(&(mq->parent)); |
| 3258 | |
| 3259 | /* initialize message queue */ |
| 3260 | |
| 3261 | /* get correct message size */ |
| 3262 | msg_align_size = RT_ALIGN(msg_size, RT_ALIGN_SIZE); |
| 3263 | mq->msg_size = msg_size; |
| 3264 | mq->max_msgs = max_msgs; |
| 3265 | |
| 3266 | /* allocate message pool */ |
| 3267 | mq->msg_pool = RT_KERNEL_MALLOC((msg_align_size + sizeof(struct rt_mq_message)) * mq->max_msgs); |
| 3268 | if (mq->msg_pool == RT_NULL) |
| 3269 | { |
| 3270 | rt_object_delete(&(mq->parent.parent)); |
| 3271 | |
| 3272 | return RT_NULL; |
| 3273 | } |
| 3274 | |
| 3275 | /* initialize message list */ |
| 3276 | mq->msg_queue_head = RT_NULL; |
| 3277 | mq->msg_queue_tail = RT_NULL; |
| 3278 | |
| 3279 | /* initialize message empty list */ |
| 3280 | mq->msg_queue_free = RT_NULL; |
| 3281 | for (temp = 0; temp < mq->max_msgs; temp ++) |
| 3282 | { |
| 3283 | head = (struct rt_mq_message *)((rt_uint8_t *)mq->msg_pool + |
| 3284 | temp * (msg_align_size + sizeof(struct rt_mq_message))); |
| 3285 | head->next = (struct rt_mq_message *)mq->msg_queue_free; |
| 3286 | mq->msg_queue_free = head; |
| 3287 | } |
| 3288 | |
| 3289 | /* the initial entry is zero */ |
| 3290 | mq->entry = 0; |
| 3291 |