MCPcopy Create free account
hub / github.com/RT-Thread/rt-thread / _can_int_tx

Function _can_int_tx

components/drivers/can/dev_can.c:161–241  ·  view source on GitHub ↗

* @internal * @brief Handles the blocking (synchronous) transmission of CAN messages. * * This function is the core of the blocking send mechanism. It iterates through * a buffer of messages to be sent. For each message, it: * 1. Acquires a hardware mailbox resource using a semaphore. * 2. Submits the message to the low-level driver for transmission. * 3. Blocks the calling thread by waitin

Source from the content-addressed store, hash-verified

159 * @return The number of bytes successfully sent.
160 */
161rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *data, int msgs)
162{
163 int size;
164 struct rt_can_tx_fifo *tx_fifo;
165
166 RT_ASSERT(can != RT_NULL);
167
168 size = msgs;
169 tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;
170 RT_ASSERT(tx_fifo != RT_NULL);
171
172 while (msgs)
173 {
174 rt_base_t level;
175 rt_uint32_t no;
176 rt_uint32_t result;
177 struct rt_can_sndbxinx_list *tx_tosnd = RT_NULL;
178
179 rt_sem_take(&(tx_fifo->sem), RT_WAITING_FOREVER);
180 level = rt_hw_local_irq_disable();
181 tx_tosnd = rt_list_entry(tx_fifo->freelist.next, struct rt_can_sndbxinx_list, list);
182 RT_ASSERT(tx_tosnd != RT_NULL);
183 rt_list_remove(&tx_tosnd->list);
184 rt_hw_local_irq_enable(level);
185
186 no = ((rt_ubase_t)tx_tosnd - (rt_ubase_t)tx_fifo->buffer) / sizeof(struct rt_can_sndbxinx_list);
187 tx_tosnd->result = RT_CAN_SND_RESULT_WAIT;
188 rt_completion_init(&tx_tosnd->completion);
189 if (can->ops->sendmsg(can, data, no) != RT_EOK)
190 {
191 /* send failed. */
192 level = rt_hw_local_irq_disable();
193 rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
194 rt_hw_local_irq_enable(level);
195 rt_sem_release(&(tx_fifo->sem));
196 goto err_ret;
197 }
198
199 can->status.sndchange |= 1<<no;
200 if (rt_completion_wait(&(tx_tosnd->completion), RT_CANSND_MSG_TIMEOUT) != RT_EOK)
201 {
202 level = rt_hw_local_irq_disable();
203 rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
204 can->status.sndchange &= ~ (1<<no);
205 rt_hw_local_irq_enable(level);
206 rt_sem_release(&(tx_fifo->sem));
207 goto err_ret;
208 }
209
210 level = rt_hw_local_irq_disable();
211 result = tx_tosnd->result;
212 if (!rt_list_isempty(&tx_tosnd->list))
213 {
214 rt_list_remove(&tx_tosnd->list);
215 }
216 rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
217 rt_hw_local_irq_enable(level);
218 rt_sem_release(&(tx_fifo->sem));

Callers 1

rt_can_writeFunction · 0.85

Calls 7

rt_sem_takeFunction · 0.85
rt_list_removeFunction · 0.85
rt_list_insert_beforeFunction · 0.85
rt_sem_releaseFunction · 0.85
rt_completion_waitFunction · 0.85
rt_list_isemptyFunction · 0.85
rt_completion_initFunction · 0.50

Tested by

no test coverage detected