Я делаю следующее во FreeRTOS:
#define DEBUG_MODE
#define COMPUTATION_TIME(taskNr) (50)
#define DELAY_TIME(taskNr) (200 * (taskNr))
#define TASK_PRIORITY(taskNr) (tskIDLE_PRIORITY + 1 + taskNr)
#define NUMBER_OF_TASKS 8
void print_chip_info(){
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
CONFIG_IDF_TARGET,
chip_info.cores,
(chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
printf("silicon revision %d, ", chip_info.revision);
printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
}
void task_implementation(void *param){
// configASSERT((uint32_t)param == 1UL);
// Task variables
taskParameters parameters = *(taskParameters *)param;
unsigned count = 0;
uint8_t taskNr = parameters.taskNr;
uint16_t computationTime = parameters.computationTime;
uint16_t delay = parameters.delay;
TickType_t xLastWakeTime;
// const TickType_t xPeriod = pdMS_TO_TICKS(delay);
// A task should always run endlessly
while (1)
{
xLastWakeTime = xTaskGetTickCount();
count++;
#ifdef DEBUG_MODE
printf("TASK %d: %d | (%d, %d) \n", taskNr, count, computationTime, delay);
printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
#endif // DEBUG MODE
while (xTaskGetTickCount() < (xLastWakeTime + computationTime));
vTaskDelayUntil(&xLastWakeTime, delay); //xPeriod
}
}
void app_main(void)
{
#ifdef DEBUG_MODE
// give MCU information
print_chip_info();
#endif // DEBUG_MODE
// Task initialization parameters
uint16_t i;
struct taskParameters *taskPtr;
taskPtr = (struct taskParameters *)malloc(NUMBER_OF_TASKS * sizeof(struct taskParameters));
char taskName[8];
uint8_t taskPriority;
for (i = 1; i <= NUMBER_OF_TASKS; ++i)
{
sprintf(taskName, "%d", i);
(taskPtr + i)->taskNr = i;
(taskPtr + i)->computationTime = COMPUTATION_TIME(i);
(taskPtr + i)->delay = DELAY_TIME(i);
taskPriority = TASK_PRIORITY(i);
xTaskCreate(&task_implementation, taskName, 2048, (taskPtr + i), taskPriority, NULL);
}
free(taskPtr);
}
Что дает в качестве вывода следующее неоднократно:
> This is esp32s3 chip with 2 CPU core(s), WiFi/BLE, silicon revision 0, 8MB external flash
> Minimum free heap size: 389352 bytes
> TASK 1: 1 | (50, 200)
> ESP-ROM:esp32s3-20210327
> Build:Mar 27 2021
> rst:0xc (RTC_SW_CPU_RST),boot:0x18 (SPI_FAST_FLASH_BOOT)
> Saved PC:0x420161b6
> SPIWP:0xee
> Octal Flash Mode Enabled
> For OPI Flash, Use Default Flash Boot Mode
> mode:SLOW_RD, clock div:1
> load:0x3fcd0108,len:0x1648
> load:0x403b6000,len:0xb7c
> load:0x403ba000,len:0x2f74
> SHA-256 comparison failed:
> Calculated: 03f53ed4905ac0ddc098b12d626ddc7ef4559209f5285446ebd397a018f229c6
> Expected: 5a5923c2b428acc85433a171e05242eb380bdafa05b6cabe2f6f177bc2db819b
> Attempting to boot anyway...
> entry 0x403b6248
> ␛[0;32mI (50) boot: ESP-IDF 4.4.1 2nd stage bootloader␛[0m
> ␛[0;32mI (50) boot: compile time 10:23:12␛[0m
> ␛[0;32mI (50) boot: chip revision: 0␛[0m
> ␛[0;32mI (52) boot.esp32s3: Boot SPI Speed : 80MHz␛[0m
> ␛[0;32mI (56) boot.esp32s3: SPI Mode : SLOW READ␛[0m
> ␛[0;32mI (62) boot.esp32s3: SPI Flash Size : 8MB␛[0m
> ␛[0;32mI (66) boot: Enabling RNG early entropy source...␛[0m
> ␛[0;32mI (72) boot: Partition Table:␛[0m
> ␛[0;32mI (75) boot: ## Label Usage Type ST Offset Length␛[0m
> ␛[0;32mI (83) boot: 0 nvs WiFi data 01 02 00009000 00006000␛[0m
> ␛[0;32mI (90) boot: 1 phy_init RF data 01 01 0000f000 00001000␛[0m
> ␛[0;32mI (98) boot: 2 factory factory app 00 00 00010000 00100000␛[0m
> ␛[0;32mI (105) boot: End of partition table␛[0m
> ␛[0;32mI (109) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=07994h ( 31124) map␛[0m
> ␛[0;32mI (125) esp_image: segment 1: paddr=000179bc vaddr=3fc906c0 size=026f8h ( 9976) load␛[0m
> ␛[0;32mI (129) esp_image: segment 2: paddr=0001a0bc vaddr=40374000 size=05f5ch ( 24412) load␛[0m
> ␛[0;32mI (142) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=16ca4h ( 93348) map␛[0m
> ␛[0;32mI (165) esp_image: segment 4: paddr=00036ccc vaddr=40379f5c size=0675ch ( 26460) load␛[0m
> ␛[0;32mI (173) esp_image: segment 5: paddr=0003d430 vaddr=50000000 size=00010h ( 16) load␛[0m
> ␛[0;32mI (178) boot: Loaded app from partition at offset 0x10000␛[0m
> ␛[0;32mI (179) boot: Disabling RNG early entropy source...␛[0m
> ␛[0;32mI (194) cpu_start: Pro cpu up.␛[0m
> ␛[0;32mI (194) cpu_start: Starting app cpu, entry point is 0x403750c4␛[0m
> ␛[0;32mI (157) cpu_start: App cpu up.␛[0m
> ␛[0;32mI (208) cpu_start: Pro cpu start user code␛[0m
> ␛[0;32mI (208) cpu_start: cpu freq: 160000000␛[0m
> ␛[0;32mI (208) cpu_start: Application information:␛[0m
> ␛[0;32mI (211) cpu_start: Project name: PioFreeRTOS␛[0m
> ␛[0;32mI (216) cpu_start: App version: 28c61da-dirty␛[0m
> ␛[0;32mI (222) cpu_start: Compile time: Jan 13 2023 10:20:15␛[0m
> ␛[0;32mI (228) cpu_start: ELF file SHA256: bc4695204a8e358a...␛[0m
> ␛[0;32mI (234) cpu_start: ESP-IDF: 4.4.1␛[0m
> ␛[0;32mI (239) heap_init: Initializing. RAM available for dynamic allocation:␛[0m
> ␛[0;32mI (246) heap_init: At 3FC93798 len 0004C868 (306 KiB): D/IRAM␛[0m
> ␛[0;32mI (252) heap_init: At 3FCE0000 len 0000EE34 (59 KiB): STACK/DRAM␛[0m
> ␛[0;32mI (259) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM␛[0m
> ␛[0;32mI (265) heap_init: At 600FE000 len 00002000 (8 KiB): RTCRAM␛[0m
> ␛[0;32mI (272) spi_flash: detected chip: mxic␛[0m
> ␛[0;33mW (276) spi_flash: Detected flash size > 16 MB, but access beyond 16 MB is not supported for this flash model yet.␛[0m
> ␛[0;32mI (287) spi_flash: flash io: dio␛[0m
> ␛[0;33mW (291) spi_flash: Detected size(32768k) larger than the size in the binary image header(8192k). Using the size in the binary image header.␛[0m
> ␛[0;32mI (305) sleep: Configure to isolate all GPIO pins in sleep state␛[0m
> ␛[0;32mI (311) sleep: Enable automatic switching of GPIO sleep configuration␛[0m
> ␛[0;32mI (318) cpu_start: Starting scheduler on PRO CPU.␛[0m
> ␛[0;32mI (0) cpu_start: Starting scheduler on APP CPU.␛[0m
Пока я использую
#define NUMBER_OF_TASKS 5
или
#define NUMBER_OF_TASKS 15
все работает нормально.
Я боролся с этим уже довольно давно, все, кажется, сужено до чего-то очень простого, но у меня все еще есть та же проблема с кодом выше.
О, и у вас есть ошибка, ведущая к определенному неопределенному поведению. Вы выделяете NUMBER_OF_TASKS
элементов для taskPtr
, но это делает сам индекс NUMBER_OF_TASKS
недействительным. Помните, что индексы массива отсчитываются от нуля.
В другом примечании, пожалуйста, используйте обычный синтаксис индексации "массива" для ваших массивов. Вместо этого лайкните taskPtr[i]
(или с текущим циклом taskPtr[i - 1]
). Его легче читать и понимать. И меньше писать.
Решение было ошибкой в массиве taskPtr. Рабочий вариант будет выглядеть следующим образом:
for (i = 0; i < NUMBER_OF_TASKS; ++i)
{
sprintf(taskName, "%d", i);
taskPtr[i].taskNr = i;
taskPtr[i].computationTime = COMPUTATION_TIME(i);
taskPtr[i].delay = DELAY_TIME(i);
taskPriority = TASK_PRIORITY(i);
xTaskCreate(&task_implementation, taskName, 2048, &taskPtr[i], taskPriority, NULL);
}
Также скорректирована индексация массива, как было упомянуто "каким-то чуваком-программистом"
Есть ли разница, если вы закомментируете
free(taskPtr)
? Это может сделать указатель недействительным до того, как задачи успеют скопировать данные.