1515#include <ipm.h>
1616#include <console/ipm_console.h>
1717#include <misc/__assert.h>
18+ #include <atomic.h>
1819
1920static void ipm_console_thread (void * arg1 , void * arg2 , void * arg3 )
2021{
2122 u8_t size32 ;
2223 u16_t type ;
23- int ret , key ;
24+ int ret ;
25+ k_spinlock_key_t key ;
2426 struct device * d ;
2527 const struct ipm_console_receiver_config_info * config_info ;
2628 struct ipm_console_receiver_runtime_data * driver_data ;
27- int pos ;
29+ int pos , end ;
30+ atomic_t * target ;
2831
2932 d = (struct device * )arg1 ;
3033 driver_data = d -> driver_data ;
3134 config_info = d -> config -> config_info ;
3235 ARG_UNUSED (arg2 );
3336 size32 = 0U ;
3437 pos = 0 ;
38+ target = config_info -> print_num ;
3539
3640 while (1 ) {
3741 k_sem_take (& driver_data -> sem , K_FOREVER );
3842
43+ key = k_spin_lock (& driver_data -> rb_spinlock );
3944 ret = ring_buf_item_get (& driver_data -> rb , & type ,
4045 (u8_t * )& config_info -> line_buf [pos ],
4146 NULL , & size32 );
47+ k_spin_unlock (& driver_data -> rb_spinlock , key );
4248 if (ret ) {
4349 /* Shouldn't ever happen... */
4450 printk ("ipm console ring buffer error: %d\n" , ret );
4551 size32 = 0U ;
4652 continue ;
4753 }
4854
55+ end = 0 ;
4956 if (config_info -> line_buf [pos ] == '\n' ||
5057 pos == config_info -> lb_size - 2 ) {
5158 if (pos != config_info -> lb_size - 2 ) {
5259 config_info -> line_buf [pos ] = '\0' ;
60+ end = 1 ;
5361 } else {
5462 config_info -> line_buf [pos + 1 ] = '\0' ;
5563 }
@@ -61,26 +69,14 @@ static void ipm_console_thread(void *arg1, void *arg2, void *arg3)
6169 printf ("%s: '%s'\n" , d -> config -> name ,
6270 config_info -> line_buf );
6371 }
72+ if (end == 1 ) {
73+ atomic_dec (target );
74+ }
6475 pos = 0 ;
6576 } else {
6677 ++ pos ;
6778 }
6879
69- /* ISR may have disabled the channel due to full buffer at
70- * some point. If that happened and there is now room,
71- * re-enable it.
72- *
73- * Lock interrupts to avoid pathological scenario where
74- * the buffer fills up in between enabling the channel and
75- * clearing the channel_disabled flag.
76- */
77- if (driver_data -> channel_disabled &&
78- ring_buf_space_get (& driver_data -> rb )) {
79- key = irq_lock ();
80- ipm_set_enabled (driver_data -> ipm_device , 1 );
81- driver_data -> channel_disabled = 0 ;
82- irq_unlock (key );
83- }
8480 }
8581}
8682
@@ -90,27 +86,20 @@ static void ipm_console_receive_callback(void *context, u32_t id,
9086 struct device * d ;
9187 struct ipm_console_receiver_runtime_data * driver_data ;
9288 int ret ;
89+ k_spinlock_key_t key ;
9390
9491 ARG_UNUSED (data );
9592 d = context ;
9693 driver_data = d -> driver_data ;
9794
95+ key = k_spin_lock (& driver_data -> rb_spinlock );
9896 /* Should always be at least one free buffer slot */
9997 ret = ring_buf_item_put (& driver_data -> rb , 0 , id , NULL , 0 );
98+ k_spin_unlock (& driver_data -> rb_spinlock , key );
10099 __ASSERT (ret == 0 , "Failed to insert data into ring buffer" );
101100 k_sem_give (& driver_data -> sem );
102101
103- /* If the buffer is now full, disable future interrupts for this channel
104- * until the thread has a chance to consume characters.
105- *
106- * This works without losing data if the sending side tries to send
107- * more characters because the sending side is making an ipm_send()
108- * call with the wait flag enabled. It blocks until the receiver side
109- * re-enables the channel and consumes the data.
110- */
111- if (ring_buf_space_get (& driver_data -> rb ) == 0 ) {
112- ipm_set_enabled (driver_data -> ipm_device , 0 );
113- driver_data -> channel_disabled = 1 ;
102+ while (ring_buf_space_get (& driver_data -> rb ) == 0 ) {
114103 }
115104}
116105
0 commit comments