1
1
/*
2
- * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
2
+ * Copyright (c) 2021-2025 Espressif Systems (Shanghai) Co., Ltd.
3
3
*
4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*/
@@ -45,11 +45,37 @@ LOG_MODULE_REGISTER(flash_esp32, CONFIG_FLASH_LOG_LEVEL);
45
45
#define ALIGN_OFFSET (num , align ) ((num) & ((align) - 1))
46
46
#endif
47
47
48
+ #ifdef CONFIG_ESP_FLASH_ASYNC_WORK
49
+ #define ESP_FLASH_WORKQUEUE_STACK_SIZE CONFIG_ESP_FLASH_ASYNC_WORK_STACK_SIZE
50
+ #define ESP_FLASH_WORKQUEUE_PRIORITY CONFIG_ESP_FLASH_ASYNC_WORK_PRIORITY
51
+ K_THREAD_STACK_DEFINE (esp_flash_workqueue_stack , ESP_FLASH_WORKQUEUE_STACK_SIZE );
52
+ static struct k_work_q esp_flash_workqueue ;
53
+ #endif /* CONFIG_ESP_FLASH_ASYNC_WORK */
54
+
55
+ #ifdef CONFIG_ESP_FLASH_ASYNC
56
+ enum {
57
+ FLASH_OP_NONE ,
58
+ FLASH_OP_READ ,
59
+ FLASH_OP_WRITE ,
60
+ FLASH_OP_ERASE
61
+ };
62
+ #endif
63
+
48
64
struct flash_esp32_dev_config {
49
65
spi_dev_t * controller ;
50
66
};
51
67
52
68
struct flash_esp32_dev_data {
69
+ #ifdef CONFIG_ESP_FLASH_ASYNC
70
+ struct k_work work ;
71
+ struct k_mutex lock ;
72
+ const struct device * dev ;
73
+ int type ;
74
+ off_t addr ;
75
+ size_t len ;
76
+ void * buf ;
77
+ int ret ;
78
+ #endif
53
79
#ifdef CONFIG_MULTITHREADING
54
80
struct k_sem sem ;
55
81
#endif
@@ -60,7 +86,7 @@ static const struct flash_parameters flash_esp32_parameters = {
60
86
.erase_value = 0xff ,
61
87
};
62
88
63
- #ifdef CONFIG_MULTITHREADING
89
+ #if defined( CONFIG_MULTITHREADING ) && !defined( CONFIG_ESP_FLASH_ASYNC )
64
90
static inline void flash_esp32_sem_take (const struct device * dev )
65
91
{
66
92
struct flash_esp32_dev_data * data = dev -> data ;
@@ -79,7 +105,7 @@ static inline void flash_esp32_sem_give(const struct device *dev)
79
105
#define flash_esp32_sem_take (dev ) do {} while (0)
80
106
#define flash_esp32_sem_give (dev ) do {} while (0)
81
107
82
- #endif /* CONFIG_MULTITHREADING */
108
+ #endif /* CONFIG_MULTITHREADING && !CONFIG_ESP_FLASH_ASYNC */
83
109
84
110
#include <zephyr/kernel.h>
85
111
#include <zephyr/logging/log.h>
@@ -374,12 +400,9 @@ static int flash_esp32_read(const struct device *dev, off_t address, void *buffe
374
400
}
375
401
#else
376
402
flash_esp32_sem_take (dev );
377
-
378
403
ret = flash_esp32_read_check_enc (address , buffer , length );
379
-
380
404
flash_esp32_sem_give (dev );
381
- #endif
382
-
405
+ #endif /* CONFIG_MCUBOOT */
383
406
if (ret != 0 ) {
384
407
LOG_ERR ("Flash read error: %d" , ret );
385
408
return - EIO ;
@@ -388,9 +411,7 @@ static int flash_esp32_read(const struct device *dev, off_t address, void *buffe
388
411
return 0 ;
389
412
}
390
413
391
- static int flash_esp32_write (const struct device * dev ,
392
- off_t address ,
393
- const void * buffer ,
414
+ static int flash_esp32_write (const struct device * dev , off_t address , const void * buffer ,
394
415
size_t length )
395
416
{
396
417
int ret = 0 ;
@@ -423,11 +444,10 @@ static int flash_esp32_write(const struct device *dev,
423
444
}
424
445
#else
425
446
ret = flash_esp32_write_check_enc (address , buffer , length );
426
- #endif
447
+ #endif /* CONFIG_ESP_FLASH_ENCRYPTION */
427
448
428
449
flash_esp32_sem_give (dev );
429
- #endif
430
-
450
+ #endif /* CONFIG_MCUBOOT */
431
451
if (ret != 0 ) {
432
452
LOG_ERR ("Flash write error: %d" , ret );
433
453
return - EIO ;
@@ -480,17 +500,94 @@ static int flash_esp32_erase(const struct device *dev, off_t start, size_t len)
480
500
}
481
501
#else
482
502
ret = esp_flash_erase_region (NULL , start , len );
483
- #endif
503
+ #endif /* CONFIG_ESP_FLASH_ENCRYPTION */
484
504
485
505
flash_esp32_sem_give (dev );
486
- #endif
506
+ #endif /* CONFIG_MCUBOOT */
487
507
if (ret != 0 ) {
488
508
LOG_ERR ("Flash erase error: %d" , ret );
489
509
return - EIO ;
490
510
}
491
511
return 0 ;
492
512
}
493
513
514
+ #ifdef CONFIG_ESP_FLASH_ASYNC
515
+ static void flash_work_handler (struct k_work * work )
516
+ {
517
+ struct flash_esp32_dev_data * data = CONTAINER_OF (work , struct flash_esp32_dev_data , work );
518
+
519
+ if (data -> type == FLASH_OP_READ ) {
520
+ data -> ret = flash_esp32_read (data -> dev , data -> addr , data -> buf , data -> len );
521
+ } else if (data -> type == FLASH_OP_WRITE ) {
522
+ data -> ret = flash_esp32_write (data -> dev , data -> addr , data -> buf , data -> len );
523
+ } else if (data -> type == FLASH_OP_ERASE ) {
524
+ data -> ret = flash_esp32_erase (data -> dev , data -> addr , data -> len );
525
+ } else {
526
+ data -> ret = -1 ;
527
+ }
528
+
529
+ k_sem_give (& data -> sem );
530
+ }
531
+
532
+ static int flash_esp32_read_async (const struct device * dev , off_t address ,
533
+ void * buffer , size_t length )
534
+ {
535
+ struct flash_esp32_dev_data * data = dev -> data ;
536
+
537
+ k_mutex_lock (& data -> lock , K_TIMEOUT_ABS_SEC (3 ));
538
+
539
+ data -> dev = dev ;
540
+ data -> addr = address ;
541
+ data -> buf = buffer ;
542
+ data -> len = length ;
543
+ data -> type = FLASH_OP_READ ;
544
+
545
+ k_work_submit (& data -> work );
546
+ k_sem_take (& data -> sem , FLASH_SEM_TIMEOUT );
547
+ k_mutex_unlock (& data -> lock );
548
+
549
+ return data -> ret ;
550
+ }
551
+
552
+ static int flash_esp32_write_async (const struct device * dev , off_t address ,
553
+ const void * buffer , size_t length )
554
+ {
555
+ struct flash_esp32_dev_data * data = dev -> data ;
556
+
557
+ k_mutex_lock (& data -> lock , K_TIMEOUT_ABS_SEC (3 ));
558
+
559
+ data -> dev = dev ;
560
+ data -> addr = address ;
561
+ data -> buf = (void * ) buffer ;
562
+ data -> len = length ;
563
+ data -> type = FLASH_OP_WRITE ;
564
+
565
+ k_work_submit (& data -> work );
566
+ k_sem_take (& data -> sem , FLASH_SEM_TIMEOUT );
567
+ k_mutex_unlock (& data -> lock );
568
+
569
+ return 0 ;
570
+ }
571
+ static int flash_esp32_erase_async (const struct device * dev , off_t start , size_t len )
572
+ {
573
+ struct flash_esp32_dev_data * data = dev -> data ;
574
+
575
+ k_mutex_lock (& data -> lock , K_TIMEOUT_ABS_SEC (3 ));
576
+
577
+ data -> addr = start ;
578
+ data -> len = len ;
579
+ data -> buf = NULL ;
580
+ data -> type = FLASH_OP_ERASE ;
581
+
582
+ k_work_submit (& data -> work );
583
+ k_sem_take (& data -> sem , FLASH_SEM_TIMEOUT );
584
+ k_mutex_unlock (& data -> lock );
585
+
586
+ return 0 ;
587
+ }
588
+ #endif
589
+
590
+
494
591
#if CONFIG_FLASH_PAGE_LAYOUT
495
592
static const struct flash_pages_layout flash_esp32_pages_layout = {
496
593
.pages_count = DT_REG_SIZE (SOC_NV_FLASH_NODE ) / FLASH_ERASE_BLK_SZ ,
@@ -504,7 +601,7 @@ void flash_esp32_page_layout(const struct device *dev,
504
601
* layout = & flash_esp32_pages_layout ;
505
602
* layout_size = 1 ;
506
603
}
507
- #endif /* CONFIG_FLASH_PAGE_LAYOUT */
604
+ #endif
508
605
509
606
static const struct flash_parameters *
510
607
flash_esp32_get_parameters (const struct device * dev )
@@ -517,18 +614,37 @@ flash_esp32_get_parameters(const struct device *dev)
517
614
static int flash_esp32_init (const struct device * dev )
518
615
{
519
616
#ifdef CONFIG_MULTITHREADING
520
- struct flash_esp32_dev_data * const dev_data = dev -> data ;
521
-
522
- k_sem_init (& dev_data -> sem , 1 , 1 );
617
+ struct flash_esp32_dev_data * const data = dev -> data ;
618
+
619
+ #ifdef CONFIG_ESP_FLASH_ASYNC
620
+ k_sem_init (& data -> sem , 0 , 1 );
621
+ k_mutex_init (& data -> lock );
622
+ k_work_init (& data -> work , flash_work_handler );
623
+
624
+ #ifdef CONFIG_ESP_FLASH_ASYNC_WORK
625
+ k_work_queue_init (& esp_flash_workqueue );
626
+ k_work_queue_start (& esp_flash_workqueue , esp_flash_workqueue_stack ,
627
+ K_THREAD_STACK_SIZEOF (esp_flash_workqueue_stack ),
628
+ ESP_FLASH_WORKQUEUE_PRIORITY , NULL );
629
+ k_work_submit_to_queue (& esp_flash_workqueue , & data -> work );
630
+ #endif
631
+ #else
632
+ k_sem_init (& data -> sem , 1 , 1 );
633
+ #endif /* CONFIG_ESP_FLASH_ASYNC */
523
634
#endif /* CONFIG_MULTITHREADING */
524
-
525
635
return 0 ;
526
636
}
527
637
528
638
static DEVICE_API (flash , flash_esp32_driver_api ) = {
639
+ #ifdef CONFIG_ESP_FLASH_ASYNC
640
+ .read = flash_esp32_read_async ,
641
+ .write = flash_esp32_write_async ,
642
+ .erase = flash_esp32_erase_async ,
643
+ #else
529
644
.read = flash_esp32_read ,
530
645
.write = flash_esp32_write ,
531
646
.erase = flash_esp32_erase ,
647
+ #endif
532
648
.get_parameters = flash_esp32_get_parameters ,
533
649
#ifdef CONFIG_FLASH_PAGE_LAYOUT
534
650
.page_layout = flash_esp32_page_layout ,
0 commit comments