Skip to content

Commit 04a930f

Browse files
nordic-krchcarlescufi
authored andcommitted
drivers: serial: nrfx_uarte: Optimize code size
Code size can significantly reduced (220 bytes per instance) if data structure (stored in RAM) is not initilized (can be moved to .bss). Data for asynchronous API had two fields which can easily be moved to the configuration structure (which is in ROM) because they do not change duing runtime. Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent 78ba608 commit 04a930f

File tree

1 file changed

+36
-35
lines changed

1 file changed

+36
-35
lines changed

drivers/serial/uart_nrfx_uarte.c

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ struct uarte_async_cb {
104104
const uint8_t *xfer_buf;
105105
size_t xfer_len;
106106

107-
uint8_t *tx_cache;
108107
size_t tx_cache_offset;
109108

110109
struct k_timer tx_timeout_timer;
@@ -131,7 +130,6 @@ struct uarte_async_cb {
131130
uint8_t rx_flush_cnt;
132131
volatile bool rx_enabled;
133132
volatile bool discard_rx_fifo;
134-
bool hw_rx_counting;
135133
bool pending_tx;
136134
/* Flag to ensure that RX timeout won't be executed during ENDRX ISR */
137135
volatile bool is_in_irq;
@@ -179,6 +177,9 @@ struct uarte_nrfx_data {
179177
/* If enabled then ENDTX is PPI'ed to TXSTOP */
180178
#define UARTE_CFG_FLAG_PPI_ENDTX BIT(1)
181179

180+
/* If enabled then TIMER and PPI is used for byte counting. */
181+
#define UARTE_CFG_FLAG_HW_BYTE_COUNTING BIT(2)
182+
182183
/* If enabled then UARTE peripheral is disabled when not used. This allows
183184
* to achieve lowest power consumption in idle.
184185
*/
@@ -224,6 +225,7 @@ struct uarte_nrfx_config {
224225
#endif
225226
#ifdef UARTE_ANY_ASYNC
226227
nrfx_timer_t timer;
228+
uint8_t *tx_cache;
227229
#endif
228230
};
229231

@@ -511,8 +513,8 @@ static int pins_state_change(const struct device *dev, bool on)
511513
/* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case
512514
* where static inline fails on linking.
513515
*/
514-
#define HW_RX_COUNTING_ENABLED(data) \
515-
(IS_ENABLED(UARTE_HW_ASYNC) ? data->async->hw_rx_counting : false)
516+
#define HW_RX_COUNTING_ENABLED(config) \
517+
(IS_ENABLED(UARTE_HW_ASYNC) ? (config->flags & UARTE_CFG_FLAG_HW_BYTE_COUNTING) : false)
516518

517519
#endif /* UARTE_ANY_ASYNC */
518520

@@ -532,7 +534,7 @@ static int uarte_enable(const struct device *dev, uint32_t mask)
532534
return ret;
533535
}
534536

535-
if (HW_RX_COUNTING_ENABLED(data) && disabled) {
537+
if (HW_RX_COUNTING_ENABLED(config) && disabled) {
536538
const nrfx_timer_t *timer = &config->timer;
537539

538540
nrfx_timer_enable(timer);
@@ -583,7 +585,7 @@ static void uart_disable(const struct device *dev)
583585
const struct uarte_nrfx_config *config = dev->config;
584586
struct uarte_nrfx_data *data = dev->data;
585587

586-
if (data->async && HW_RX_COUNTING_ENABLED(data)) {
588+
if (data->async && HW_RX_COUNTING_ENABLED(config)) {
587589
nrfx_timer_disable(&config->timer);
588590
/* Timer/counter value is reset when disabled. */
589591
data->async->rx_total_byte_cnt = 0;
@@ -608,7 +610,7 @@ static int uarte_nrfx_rx_counting_init(const struct device *dev)
608610
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
609611
int ret;
610612

611-
if (HW_RX_COUNTING_ENABLED(data)) {
613+
if (HW_RX_COUNTING_ENABLED(cfg)) {
612614
nrfx_timer_config_t tmr_config = NRFX_TIMER_DEFAULT_CONFIG(
613615
NRF_TIMER_BASE_FREQUENCY_GET(cfg->timer.p_reg));
614616

@@ -618,20 +620,18 @@ static int uarte_nrfx_rx_counting_init(const struct device *dev)
618620
&tmr_config,
619621
timer_handler);
620622
if (ret != NRFX_SUCCESS) {
621-
LOG_ERR("Timer already initialized, "
622-
"switching to software byte counting.");
623-
data->async->hw_rx_counting = false;
623+
LOG_ERR("Timer already initialized");
624+
return -EINVAL;
624625
} else {
625626
nrfx_timer_enable(&cfg->timer);
626627
nrfx_timer_clear(&cfg->timer);
627628
}
628629

629630
ret = gppi_channel_alloc(&data->async->rx_cnt.ppi);
630631
if (ret != NRFX_SUCCESS) {
631-
LOG_ERR("Failed to allocate PPI Channel, "
632-
"switching to software byte counting.");
633-
data->async->hw_rx_counting = false;
632+
LOG_ERR("Failed to allocate PPI Channel");
634633
nrfx_timer_uninit(&cfg->timer);
634+
return -EINVAL;
635635
}
636636

637637
#if CONFIG_HAS_HW_NRF_PPI
@@ -729,8 +729,10 @@ static void start_tx_locked(const struct device *dev, struct uarte_nrfx_data *da
729729
*
730730
* @return True if cache was set, false if no more data to put in cache.
731731
*/
732-
static bool setup_tx_cache(struct uarte_nrfx_data *data)
732+
static bool setup_tx_cache(const struct device *dev)
733733
{
734+
struct uarte_nrfx_data *data = dev->data;
735+
const struct uarte_nrfx_config *config = dev->config;
734736
size_t remaining = data->async->tx_size - data->async->tx_cache_offset;
735737

736738
if (!remaining) {
@@ -740,8 +742,8 @@ static bool setup_tx_cache(struct uarte_nrfx_data *data)
740742
size_t len = MIN(remaining, CONFIG_UART_ASYNC_TX_CACHE_SIZE);
741743

742744
data->async->xfer_len = len;
743-
data->async->xfer_buf = data->async->tx_cache;
744-
memcpy(data->async->tx_cache, &data->async->tx_buf[data->async->tx_cache_offset], len);
745+
data->async->xfer_buf = config->tx_cache;
746+
memcpy(config->tx_cache, &data->async->tx_buf[data->async->tx_cache_offset], len);
745747

746748
return true;
747749
}
@@ -782,7 +784,7 @@ static int uarte_nrfx_tx(const struct device *dev, const uint8_t *buf,
782784
data->async->xfer_len = len;
783785
} else {
784786
data->async->tx_cache_offset = 0;
785-
(void)setup_tx_cache(data);
787+
(void)setup_tx_cache(dev);
786788
}
787789

788790
start_tx_locked(dev, data);
@@ -1019,7 +1021,7 @@ static void rx_timeout(struct k_timer *timer)
10191021
nrf_uarte_int_disable(get_uarte_instance(dev),
10201022
NRF_UARTE_INT_ENDRX_MASK);
10211023

1022-
if (HW_RX_COUNTING_ENABLED(data)) {
1024+
if (HW_RX_COUNTING_ENABLED(cfg)) {
10231025
read = nrfx_timer_capture(&cfg->timer, 0);
10241026
} else {
10251027
read = data->async->rx_cnt.cnt;
@@ -1038,7 +1040,7 @@ static void rx_timeout(struct k_timer *timer)
10381040
int32_t len = data->async->rx_total_byte_cnt
10391041
- data->async->rx_total_user_byte_cnt;
10401042

1041-
if (!HW_RX_COUNTING_ENABLED(data) &&
1043+
if (!HW_RX_COUNTING_ENABLED(cfg) &&
10421044
(len < 0)) {
10431045
/* Prevent too low value of rx_cnt.cnt which may occur due to
10441046
* latencies in handling of the RXRDY interrupt.
@@ -1374,7 +1376,7 @@ static void txstopped_isr(const struct device *dev)
13741376
*/
13751377
if (amount == data->async->xfer_len) {
13761378
data->async->tx_cache_offset += amount;
1377-
if (setup_tx_cache(data)) {
1379+
if (setup_tx_cache(dev)) {
13781380
key = irq_lock();
13791381
start_tx_locked(dev, data);
13801382
irq_unlock(key);
@@ -1412,10 +1414,12 @@ static void uarte_nrfx_isr_async(const void *arg)
14121414
{
14131415
const struct device *dev = arg;
14141416
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
1415-
struct uarte_nrfx_data *data = dev->data;
1417+
const struct uarte_nrfx_config *config = dev->config;
14161418

1417-
if (!HW_RX_COUNTING_ENABLED(data)
1419+
if (!HW_RX_COUNTING_ENABLED(config)
14181420
&& nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_RXDRDY)) {
1421+
struct uarte_nrfx_data *data = dev->data;
1422+
14191423
nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_RXDRDY);
14201424
data->async->rx_cnt.cnt++;
14211425
return;
@@ -1915,7 +1919,7 @@ static int uarte_nrfx_pm_action(const struct device *dev,
19151919

19161920
#ifdef UARTE_ANY_ASYNC
19171921
if (data->async) {
1918-
if (HW_RX_COUNTING_ENABLED(data)) {
1922+
if (HW_RX_COUNTING_ENABLED(cfg)) {
19191923
nrfx_timer_enable(&cfg->timer);
19201924
}
19211925

@@ -2054,8 +2058,12 @@ static int uarte_nrfx_pm_action(const struct device *dev,
20542058
#define UART_NRF_UARTE_DEVICE(idx) \
20552059
NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(UARTE(idx)); \
20562060
UARTE_INT_DRIVEN(idx); \
2057-
UARTE_ASYNC(idx); \
20582061
PINCTRL_DT_DEFINE(UARTE(idx)); \
2062+
IF_ENABLED(CONFIG_UART_##idx##_ASYNC, ( \
2063+
static uint8_t \
2064+
uarte##idx##_tx_cache[CONFIG_UART_ASYNC_TX_CACHE_SIZE] \
2065+
UARTE_MEMORY_SECTION(idx); \
2066+
struct uarte_async_cb uarte##idx##_async;)) \
20592067
static uint8_t uarte##idx##_char_out UARTE_MEMORY_SECTION(idx); \
20602068
static uint8_t uarte##idx##_rx_data UARTE_MEMORY_SECTION(idx); \
20612069
static struct uarte_nrfx_data uarte_##idx##_data = { \
@@ -2082,8 +2090,12 @@ static int uarte_nrfx_pm_action(const struct device *dev,
20822090
UARTE_CFG_FLAG_GPIO_MGMT : 0) | \
20832091
(IS_ENABLED(CONFIG_UART_##idx##_ENHANCED_POLL_OUT) ? \
20842092
UARTE_CFG_FLAG_PPI_ENDTX : 0) | \
2093+
(IS_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC) ? \
2094+
UARTE_CFG_FLAG_HW_BYTE_COUNTING : 0) | \
20852095
USE_LOW_POWER(idx), \
20862096
UARTE_DISABLE_RX_INIT(UARTE(idx)), \
2097+
IF_ENABLED(CONFIG_UART_##idx##_ASYNC, \
2098+
(.tx_cache = uarte##idx##_tx_cache,)) \
20872099
IF_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC, \
20882100
(.timer = NRFX_TIMER_INSTANCE( \
20892101
CONFIG_UART_##idx##_NRF_HW_ASYNC_TIMER),)) \
@@ -2112,17 +2124,6 @@ static int uarte_nrfx_pm_action(const struct device *dev,
21122124
CONFIG_SERIAL_INIT_PRIORITY, \
21132125
&uart_nrfx_uarte_driver_api)
21142126

2115-
#define UARTE_ASYNC(idx) \
2116-
IF_ENABLED(CONFIG_UART_##idx##_ASYNC, ( \
2117-
static uint8_t \
2118-
uarte##idx##_tx_cache[CONFIG_UART_ASYNC_TX_CACHE_SIZE] \
2119-
UARTE_MEMORY_SECTION(idx); \
2120-
struct uarte_async_cb uarte##idx##_async = { \
2121-
.tx_cache = uarte##idx##_tx_cache, \
2122-
.hw_rx_counting = \
2123-
IS_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC), \
2124-
}))
2125-
21262127
#define UARTE_INT_DRIVEN(idx) \
21272128
IF_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \
21282129
(static uint8_t uarte##idx##_tx_buffer \

0 commit comments

Comments
 (0)