diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index 288ee80a7ad5c4796b1ca9a3c819abe215a634a5..f5d0147c4dfbd292d122df04af5203e7a69aeea1 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -1,3 +1,181 @@ +# Phytium FreeRTOS SDK 2024-05-10 ChangeLog + +Change Log since 2024-05-10 + +## example + +- modify i2c example readme and cmd + +# Phytium FreeRTOS SDK 2024-05-09 ChangeLog + +Change Log since 2024-05-09 + +## example + +- modify freertos feature resource example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-05-09 ChangeLog + +Change Log since 2024-05-09 + +## example + +- modify software_timer example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-05-09 ChangeLog + +Change Log since 2024-05-08 + +## example + +- modify wlan example, add no letter shell mode, adapt to auto-test system + +## third-party + +- repair iomux init bug + +# Phytium FreeRTOS SDK 2024-05-08 ChangeLog + +Change Log since 2024-05-07 + +## example + +- modify task_notify example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-05-07 ChangeLog + +Change Log since 2024-05-06 + +## example + +- modify freertos feature queue example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-05-07 ChangeLog + +Change Log since 2024-05-06 + +## example + +- modify event group example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-05-06 ChangeLog + +Change Log since 2024-05-06 + +## example + +- modify freertos feature interrupt example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-05-06 ChangeLog + +Change Log since 2024-04-30 + +## example + +- modify fatfs example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-04-30 ChangeLog + +Change Log since 2024-04-30 + +## example + +- modify posix example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-04-30 ChangeLog + +Change Log since 2024-04-30 + +## example + +- modify tacho and timer example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-04-30 ChangeLog + +Change Log since 2024-04-30 + +## example + +- modify atomic example, add no letter shell mode, adapt to auto-test system +- modify nested_interrupt example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-04-29 ChangeLog + +Change Log since 2024-04-29 + +## example + +- modify lwip_startup example, add no letter shell mode, adapt to auto-test system +- modify lwip_iperf example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-04-29 ChangeLog + +Change Log since 2024-04-29 + +## example + +- modify wdt example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-04-29 ChangeLog + +Change Log since 2024-04-28 + +## example + +- Refactoring peripheral i2s example + +# Phytium FreeRTOS SDK 2024-04-29 ChangeLog + +Change Log since 2024-04-26 + +## example + +- modify i2c example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-04-28 ChangeLog + +Change Log since 2024-04-26 + +## example + +- modify qspi_spiffs example, add no letter shell mode, adapt to auto-test system + +# Phytium FreeRTOS SDK 2024-04-26 ChangeLog + +Change Log since 2024-04-26 + +## example + +- modify spiffs example, add no letter shell mode, adapt to auto-test system + +## third party + +- repair spiffs deinit bug + +# Phytium FreeRTOS SDK 2024-04-26 ChangeLog + +Change Log since 2024-04-25 + +## tools + +- Unified rtos and standalone compilation printing information + +# Phytium FreeRTOS SDK 2024-04-26 ChangeLog + +Change Log since 2024-04-25 + +## example + +- Refactoring peripheral sdif example + +# Phytium FreeRTOS SDK 2024-04-26 ChangeLog + +Change Log since 2024-04-25 + +## example + +- Refactoring peripheral canfd example + # Phytium FreeRTOS SDK 2024-04-25 ChangeLog Change Log since 2024-04-25 diff --git a/drivers/adc/fadc_os.c b/drivers/adc/fadc_os.c index 5c1e72172c6d4d35f32ff15d2d26e4e3ddda65b0..9e9f17ad2f50fcb5ba4141e05412e0ba68cc324b 100644 --- a/drivers/adc/fadc_os.c +++ b/drivers/adc/fadc_os.c @@ -56,7 +56,7 @@ static FFreeRTOSAdc os_adc[FADC_NUM] = {0}; /** * @name: FFreeRTOSAdcControl - * @msg: control freeRTOS adc instance + * @msg: control FreeRTOS adc instance * @param {FFreeRTOSAdc} *os_adc_p, pointer to os adc instance * @param {int} cmd, control cmd * @param {void} *args, pointer to control cmd arguments @@ -132,7 +132,7 @@ static FError FFreeRTOSAdcControl(FFreeRTOSAdc *os_adc_p, int cmd, void *arg) /** * @name: FFreeRTOSAdcSet - * @msg: set freeRTOS adc channel config, include div, mode + * @msg: set FreeRTOS adc channel config, include div, mode * @param {FFreeRTOSAdc} *os_adc_p, pointer to os adc instance * @param {FAdcConvertConfig} *adc_cfg_p, adc config parameters * @return err code information, FADC_SUCCESS indicates success,others indicates failed @@ -203,7 +203,7 @@ static FError FFreeRTOSAdcChannelThresholdSet(FFreeRTOSAdc *os_adc_p, FAdcChanne /** * @name: FFreeRTOSAdcEnable - * @msg: enable or disable freeRTOS adc channel output + * @msg: enable or disable FreeRTOS adc channel output * @param {FFreeRTOSAdc} *os_adc_p, pointer to os adc instance * @param {FAdcChannel} channel, adc channel * @param {boolean} state, TRUE-enable, FALSE-disable @@ -267,7 +267,7 @@ static FError FFreeRTOSAdcInterruptEnable(FFreeRTOSAdc *os_adc_p, FAdcChannel ch /** * @name: FFreeRTOSAdcInit - * @msg: init freeRTOS adc instance, include init adc and create mutex + * @msg: init FreeRTOS adc instance, include init adc and create mutex * @param {u32} instance_id, adc instance id * @return {FFreeRTOSAdc *} pointer to os adc instance */ @@ -288,7 +288,7 @@ FFreeRTOSAdc *FFreeRTOSAdcInit(u32 instance_id) /** * @name: FFreeRTOSAdcDeinit - * @msg: deinit freeRTOS adc instance, include stop adc, deinit adc and delete mutex + * @msg: deinit FreeRTOS adc instance, include stop adc, deinit adc and delete mutex * @param {FFreeRTOSAdc} *os_adc_p, pointer to os adc instance * @return err code information, FADC_SUCCESS indicates success,others indicates failed */ diff --git a/drivers/can/fcan_os.c b/drivers/can/fcan_os.c index 4ef3cfbc403b8e17735a101dd424b2e074b40d96..d4c216b45565c105d0c31ca9f84b85f367e3cb26 100644 --- a/drivers/can/fcan_os.c +++ b/drivers/can/fcan_os.c @@ -46,7 +46,7 @@ static FFreeRTOSCan os_can[FCAN_NUM] = {0}; /** * @name: FFreeRTOSCanInit - * @msg: init freeRTOS can instance, include init can and create mutex + * @msg: init FreeRTOS can instance, include init can and create mutex * @param {u32} instance_id, can instance id * @return {FFreeRTOSCan *} pointer to os can instance */ @@ -67,7 +67,7 @@ FFreeRTOSCan *FFreeRTOSCanInit(u32 instance_id) /** * @name: FFreeRTOSCanDeinit - * @msg: deinit freeRTOS can instance, include stop can, deinit can and delete mutex + * @msg: deinit FreeRTOS can instance, include stop can, deinit can and delete mutex * @param {FFreeRTOSCan} *os_can_p, pointer to os can instance * @return err code information, FCAN_SUCCESS indicates success,others indicates failed */ @@ -85,7 +85,7 @@ FError FFreeRTOSCanDeinit(FFreeRTOSCan *os_can_p) /** * @name: FFreeRTOSCanControl - * @msg: control freeRTOS can instance + * @msg: control FreeRTOS can instance * @param {FFreeRTOSCan} *os_can_p, pointer to os can instance * @param {int} cmd, control cmd * @param {void} *args, pointer to control cmd arguments diff --git a/drivers/dma/fgdma/fgdma_os.c b/drivers/dma/fgdma/fgdma_os.c index a4f54ac82458719e5b9b1fcaeb281dbe993bceb9..e281e8516fdb202af19eb238cd21028afde9e9fb 100644 --- a/drivers/dma/fgdma/fgdma_os.c +++ b/drivers/dma/fgdma/fgdma_os.c @@ -287,7 +287,7 @@ FError FFreeRTOSGdmaChanConfigure(FFreeRTOSGdma *const instance_p, } channel_first_desc_addr[channel_id] = first_desc_addr; - /* creat BDL descriptor list */ + /* create BDL descriptor list */ FGdmaBdlDescConfig bdl_desc_config[channel_config.valid_desc_num]; s32 pre_desc_trans_len = os_channel_config_p->trans_length / channel_config.valid_desc_num; for (s32 loop = 0; loop < channel_config.valid_desc_num; loop++) diff --git a/drivers/i2c/fi2c_os.c b/drivers/i2c/fi2c_os.c index 368a35e18ad6e759d93a888673e8c308ff4a982c..c921a5e3737c965803bc4f85daee49e5840ad14d 100644 --- a/drivers/i2c/fi2c_os.c +++ b/drivers/i2c/fi2c_os.c @@ -38,8 +38,6 @@ #include "fmio_hw.h" #include "fmio.h" -static FMioCtrl i2c_master; -static FMioCtrl i2c_slave; static FFreeRTOSI2c os_i2c[FMIO_NUM] = {0}; /* virtual eeprom memory */ @@ -77,7 +75,7 @@ static void FI2cOsResetInterrupt(FI2c *pctrl) /** * @name: FFreeRTOSI2cInit - * @msg: init freeRTOS i2c instance + * @msg: init FreeRTOS i2c instance * @return {FFreeRTOSI2c *}pointer to os i2c instance * @param {u32} instance_id,i2c instance_id */ @@ -100,29 +98,20 @@ FFreeRTOSI2c *FFreeRTOSI2cInit(u32 instance_id, u32 work_mode, u32 slave_address } const FMioConfig *mio_config_p ; - FMioCtrl *pctrl; - if (work_mode == FI2C_MASTER) - { - pctrl = &i2c_master; - } - else - { - pctrl = &i2c_slave; - } - + FMioCtrl pctrl; + /*获取任意I2C控制器默认配置,作为MIO复用为I2C默认配置*/ i2c_config = *FI2cLookupConfig(0); - mio_config_p = FMioLookupConfig(instance_id); + if (NULL == mio_config_p) { vPrintf("Config of mio_i2c instance %d non found.\r\n", instance_id); return NULL; } + pctrl.config = *mio_config_p; - pctrl->config = *mio_config_p; - - err = FMioFuncInit(pctrl, FMIO_FUNC_SET_I2C); + err = FMioFuncInit(&pctrl, FMIO_FUNC_SET_I2C); if (err != FREERTOS_I2C_SUCCESS) { vPrintf("Mio I2c initialize is error.\r\n "); @@ -133,19 +122,16 @@ FFreeRTOSI2c *FFreeRTOSI2cInit(u32 instance_id, u32 work_mode, u32 slave_address i2c_config.work_mode = work_mode; i2c_config.slave_addr = slave_address; i2c_config.speed_rate = speed_rate; + i2c_config.instance_id = pctrl.config.instance_id; + i2c_config.base_addr = pctrl.config.func_base_addr; + i2c_config.irq_num = pctrl.config.irq_num; - if (work_mode == FI2C_MASTER)/* 主机中断优先级低于从机接收 */ + if (work_mode == FI2C_MASTER)/* 主机中断优先级高于从机接收 */ { - i2c_config.instance_id = i2c_master.config.instance_id; - i2c_config.base_addr = i2c_master.config.func_base_addr; - i2c_config.irq_num = i2c_master.config.irq_num; i2c_config.irq_prority = I2C_MASTER_IRQ_PRORITY; } - else + else if (work_mode == FI2C_SLAVE) { - i2c_config.instance_id = i2c_slave.config.instance_id; - i2c_config.base_addr = i2c_slave.config.func_base_addr; - i2c_config.irq_num = i2c_slave.config.irq_num; i2c_config.irq_prority = I2C_SLAVE_IRQ_PRORITY; } @@ -160,12 +146,13 @@ FFreeRTOSI2c *FFreeRTOSI2cInit(u32 instance_id, u32 work_mode, u32 slave_address { FI2cOsSetupInterrupt(&os_i2c[instance_id].i2c_device); } + return (&os_i2c[instance_id]); } /** * @name: FFreeRTOSI2cDeinit - * @msg: deinit freeRTOS i2c instance, include deinit i2c and delete mutex semaphore + * @msg: deinit FreeRTOS i2c instance, include deinit i2c and delete mutex semaphore * @return {*}无 * @param {FFreeRTOSI2c} *os_i2c_p,pointer to os i2c instance */ @@ -173,8 +160,7 @@ void FFreeRTOSI2cDeinit(FFreeRTOSI2c *os_i2c_p) { FASSERT(os_i2c_p); FASSERT(os_i2c_p->wr_semaphore != NULL); - FMioCtrl *pctrl = &i2c_master; - FMioFuncDeinit(pctrl); + /* 避免没有关闭中断,存在触发 */ InterruptMask(os_i2c_p->i2c_device.config.irq_num); FI2cDeInitialize(&os_i2c_p->i2c_device); diff --git a/drivers/i2c/fi2c_os.h b/drivers/i2c/fi2c_os.h index 58a32087037929481f6fa754a73c87f587def35a..5decab62e840fc6207b8ba10c94db476dc9d79bd 100644 --- a/drivers/i2c/fi2c_os.h +++ b/drivers/i2c/fi2c_os.h @@ -103,10 +103,10 @@ enum /*选择操作I2C的方式*/ }; /************************** Function Prototypes ******************************/ -/* init freeRTOS i2c instance */ +/* init FreeRTOS i2c instance */ FFreeRTOSI2c *FFreeRTOSI2cInit(u32 instance_id, u32 work_mode, u32 slave_address, u32 speed_rate); -/* deinit freeRTOS i2c instance */ +/* deinit FreeRTOS i2c instance */ void FFreeRTOSI2cDeinit(FFreeRTOSI2c *os_i2c_p); /* tranfer i2c mesage */ diff --git a/drivers/i2s/fi2s_os.c b/drivers/i2s/fi2s_os.c index 9e12ed0cd4ef4dce47404da9fcf76a5e2b13b566..0330c513ee0bd0e07a4fc3292924fd523bd278ab 100644 --- a/drivers/i2s/fi2s_os.c +++ b/drivers/i2s/fi2s_os.c @@ -13,7 +13,7 @@ * * FilePath: fi2s_os.c * Created Date: 2024-02-29 10:49:34 - * Last Modified: 2024-03-07 10:09:12 + * Last Modified: 2024-04-26 15:11:27 * Description: This file is for i2s driver * * Modify History: @@ -31,13 +31,10 @@ #include "fparameters.h" #include "fparameters_comm.h" #include "fdebug.h" -#include "fio_mux.h" -#include "fmio_hw.h" -#include "fmio.h" +#include "fassert.h" #include "ferror_code.h" #include "fi2s_os.h" - /************************** Variable Definitions *****************************/ static FFreeRTOSI2s i2s; /***************** Macros (Inline Functions) Definitions *********************/ @@ -62,7 +59,6 @@ static void FFreeRTOSI2SSetupInterrupt(FI2s *ctrl) FError err = FFREERTOS_I2S_SUCCESS; GetCpuId(&cpu_id); - vPrintf("cpu_id is %d \r\n", cpu_id); InterruptSetTargetCpus(config->irq_num, cpu_id); /* umask i2s irq */ InterruptSetPriority(config->irq_num, config->irq_prority); @@ -104,13 +100,34 @@ err_exit: return (FFREERTOS_I2S_SUCCESS == err) ? instance : NULL; /* exit with NULL if failed */ } +/** + * @name: FFreeRTOSSetupI2S + * @msg: set the i2s controller to work + * @param {FFreeRTOSI2s} *os_i2s_p, the instance of i2s + * @return Null + */ +FError FFreeRTOSSetupI2S(FFreeRTOSI2s *os_i2s_p) +{ + FASSERT(os_i2s_p); + FI2s *ctrl = &os_i2s_p->i2s_ctrl; + FError err = FT_SUCCESS; + err = FI2sClkOutDiv(ctrl); /* 默认16-bits采集 */ + if (FT_SUCCESS != err) + { + FI2S_ERROR("Set i2s failed, err: 0x%x!!!", err); + return err; + } + FI2sSetHwconfig(ctrl); + FI2sTxRxEnable(ctrl, TRUE); + return err; +} + /** * @name: FFreeRTOSI2SDeinit * @msg: 去初始化i2s控制器 * @param {FFreeRTOSI2s} *os_i2s_p, the instance of i2s * @return Null */ - FError FFreeRTOSI2SDeinit(FFreeRTOSI2s *os_i2s_p) { FASSERT(os_i2s_p); diff --git a/drivers/i2s/fi2s_os.h b/drivers/i2s/fi2s_os.h index 2d2fb1f896b2e786a46cef3fe970d35921731702..365ec0fd98682aea554bf649cba2c9d9d97044f9 100644 --- a/drivers/i2s/fi2s_os.h +++ b/drivers/i2s/fi2s_os.h @@ -13,7 +13,7 @@ * * FilePath: fi2s_os.h * Created Date: 2024-02-29 10:49:34 - * Last Modified: 2024-03-28 11:07:07 + * Last Modified: 2024-04-26 14:54:58 * Description: This file is for providing function related definitions of i2s driver * * Modify History: @@ -54,6 +54,9 @@ typedef struct /*init the i2s and return the i2s instance*/ FFreeRTOSI2s *FFreeRTOSI2sInit(u32 id); +/*setup the i2s */ +FError FFreeRTOSSetupI2S(FFreeRTOSI2s *os_i2s_p); + /*deinit the i2s */ FError FFreeRTOSI2SDeinit(FFreeRTOSI2s *os_i2s_p); diff --git a/drivers/pwm/fpwm_os.c b/drivers/pwm/fpwm_os.c index 1d6e0674702a92f32354c00dde9d1387817f6ad4..f56f435616cbed7a9a5b732dd78dddfa342c6552 100644 --- a/drivers/pwm/fpwm_os.c +++ b/drivers/pwm/fpwm_os.c @@ -44,7 +44,7 @@ static FFreeRTOSPwm os_pwm[FPWM_NUM] = {0}; /** * @name: FFreeRTOSPwmInit - * @msg: init freeRTOS pwm instance, include init pwm and create mutex + * @msg: init FreeRTOS pwm instance, include init pwm and create mutex * @param {u32} instance_id, pwm instance id * @return {FFreeRTOSPwm *} pointer to os pwm instance */ @@ -66,7 +66,7 @@ FFreeRTOSPwm *FFreeRTOSPwmInit(u32 instance_id) /** * @name: FFreeRTOSPwmDeinit - * @msg: deinit freeRTOS pwm instance, include stop pwm, deinit pwm and delete mutex + * @msg: deinit FreeRTOS pwm instance, include stop pwm, deinit pwm and delete mutex * @param {FFreeRTOSPwm} *os_pwm_p, pointer to os pwm instance * @return err code information, FPWM_SUCCESS indicates success,others indicates failed */ @@ -84,7 +84,7 @@ FError FFreeRTOSPwmDeinit(FFreeRTOSPwm *os_pwm_p) /** * @name: FFreeRTOSPwmControl - * @msg: control freeRTOS pwm instance + * @msg: control FreeRTOS pwm instance * @param {FFreeRTOSPwm} *os_pwm_p, pointer to os pwm instance * @param {int} cmd, control cmd * @param {void} *args, pointer to control cmd arguments @@ -152,7 +152,7 @@ static FError FFreeRTOSPwmControl(FFreeRTOSPwm *os_pwm_p, int cmd, void *arg) /** * @name: FFreeRTOSPwmSet - * @msg: set freeRTOS pwm channel config, include div, period and pulse. + * @msg: set FreeRTOS pwm channel config, include div, period and pulse. * @param {FFreeRTOSPwm} *os_pwm_p, pointer to os pwm instance * @param {u8} channel, pwm channel * @param {FPwmVariableConfig} pwm_cfg_p, pwm config parameters, include mode and duty @@ -174,7 +174,7 @@ FError FFreeRTOSPwmSet(FFreeRTOSPwm *os_pwm_p, u8 channel, FPwmVariableConfig *p /** * @name: FFreeRTOSPwmGet - * @msg: get freeRTOS pwm channel config, include div, period and pulse. + * @msg: get FreeRTOS pwm channel config, include div, period and pulse. * @param {FFreeRTOSPwm} *os_pwm_p, pointer to os pwm instance * @param {u8} channel, pwm channel * @param {FPwmVariableConfig} *pwm_cfg_p, pwm config parameters, include mode and duty @@ -200,7 +200,7 @@ FError FFreeRTOSPwmGet(FFreeRTOSPwm *os_pwm_p, u8 channel, FPwmVariableConfig *p /** * @name: FFreeRTOSPwmEnable - * @msg: enable or disable freeRTOS pwm channel output + * @msg: enable or disable FreeRTOS pwm channel output * @param {FFreeRTOSPwm} *os_pwm_p, pointer to os pwm instance * @param {u8} channel, pwm channel * @param {boolean} state, TRUE-enable, FALSE-disable @@ -272,7 +272,7 @@ FError FFreeRTOSPwmDbGet(FFreeRTOSPwm *os_pwm_p, FPwmDbVariableConfig *db_cfg_p) /** * @name: FFreeRTOSPwmPulseSet - * @msg: set freeRTOS pwm channel pulse. + * @msg: set FreeRTOS pwm channel pulse. * @param {FFreeRTOSPwm} *os_pwm_p, pointer to os pwm instance * @param {u8} channel, pwm channel * @param {u16} pulse, pwm pulse to set diff --git a/drivers/qspi/fqspi/fqspi_os.h b/drivers/qspi/fqspi/fqspi_os.h index edadca97fe4e4ddffbbdbe3a4d9cc72341b81d33..6e822553e56fb3cef0ffbab5fc18ae1992f5bc54 100644 --- a/drivers/qspi/fqspi/fqspi_os.h +++ b/drivers/qspi/fqspi/fqspi_os.h @@ -59,10 +59,10 @@ typedef struct xSemaphoreHandle wr_semaphore; /*!< qspi read and write semaphore for resource sharing */ } FFreeRTOSQspi; -/* init freeRTOS qspi instance */ +/* init FreeRTOS qspi instance */ FFreeRTOSQspi *FFreeRTOSQspiInit(u32 instance_id); -/* deinit freeRTOS qspi instance */ +/* deinit FreeRTOS qspi instance */ void FFreeRTOSQspiDeinit(FFreeRTOSQspi *os_qspi_p); /* tranfer qspi mesage */ diff --git a/drivers/timer/ftimer_tacho_os.c b/drivers/timer/ftimer_tacho_os.c index dd3f1728c5f5eafbd08e571ac52e54b6a623f8b2..0bf962f8677ece3743cae353b1adfbe6618f1e25 100644 --- a/drivers/timer/ftimer_tacho_os.c +++ b/drivers/timer/ftimer_tacho_os.c @@ -60,105 +60,7 @@ static FFreeRTOSTimerTacho os_timer_tacho[38] = {0}; /************************** Variable Definitions *****************************/ -typedef struct -{ - u32 id; /* id of tacho */ - boolean work_mode; /*tacho or capture*/ - boolean bits32; /*otherwise 64 bit*/ - boolean restart_mode; /*otherwise free-run*/ - u8 edge_mode; /* rising falling or double edge*/ - u8 jitter_level; /* anti_jitter_number 0~3 */ - u32 plus_num; /* plus_num of period to calculate rpm */ -} FFreeRTOSTachoConfigs; - -typedef struct -{ - u32 id; /* id of timer */ - boolean bits32; /*otherwise 64 bit*/ - boolean restartmode; /*otherwise free-run*/ - boolean cyc_cmp; /*otherwise once cmp*/ - boolean clear_cnt; /*otherwise not clear*/ - boolean forceload; /*otherwise not force-load*/ - u32 startcnt; /*start cnt num*/ - u32 cmptick32; /*32bit cnt num*/ - u64 cmptick64; /*64bit cnt num*/ -} FFreeRTOSTimerConfigs; - -static FFreeRTOSTimerConfigs timercfg; -static FFreeRTOSTachoConfigs tachocfg; - /************************** Function Prototypes ******************************/ - -/** - * @name: FTimerCfgInit - * @msg: 加载转换后配置项,并完成初始化操作,定时器处于就绪状态 - * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败 - * @param {TimerTestConfigs} *timercfg_p 可操作的配置参数结构体 - */ -static FError FTimerCfgInit(const FFreeRTOSTimerConfigs *timercfg_p, FTimerTachoCtrl *timer) -{ - FASSERT(timercfg_p); - FASSERT(timer); - FError ret = FREERTOS_TIMER_TACHO_SUCCESS; - - FTimerTachoConfig *pconfig = &timer->config; - - FTimerGetDefConfig(timercfg_p->id, pconfig); - - if (timercfg_p->restartmode) - { - pconfig->timer_mode = FTIMER_RESTART; - } - else - { - pconfig->timer_mode = FTIMER_FREE_RUN; - } - - if (timercfg_p->bits32) - { - pconfig->timer_bits = FTIMER_32_BITS; - } - else - { - pconfig->timer_bits = FTIMER_64_BITS; - } - - if (timercfg_p->cyc_cmp) - { - pconfig->cmp_type = FTIMER_CYC_CMP; - } - else - { - pconfig->cmp_type = FTIMER_ONCE_CMP; - } - - ret = FTimerInit(timer, pconfig); - if (FREERTOS_TIMER_TACHO_SUCCESS != ret) - { - return ret; - } - - /*将时间参数us装换成计时器的ticks,我们设置StartTick,将CmpTick设置为最大*/ - ret = FTimerSetStartVal(timer, timercfg.startcnt); - if (FREERTOS_TIMER_TACHO_SUCCESS != ret) - { - return ret; - } - - if (timercfg_p->bits32) - { - ret |= FTimerSetPeriod32(timer, timercfg.cmptick32); - } - else - { - ret |= FTimerSetPeriod64(timer, timercfg.cmptick64); - } - - FTIMER_OS_INFO("Timer Init finished."); - - return ret; -} - /** * @name: FTimerFunctionInit * @msg: timer init. @@ -171,36 +73,55 @@ FFreeRTOSTimerTacho *FFreeRTOSTimerInit(u32 id, boolean timer_mode, u64 times) { FASSERT_MSG(id < FTIMER_NUM, "Invalid timer id."); FASSERT_MSG(FT_COMPONENT_IS_READY != os_timer_tacho[id].ctrl.isready, "timer_tacho ready."); + FError ret = FREERTOS_TIMER_TACHO_SUCCESS; + u64 cnttick = 0; + u32 startcnt = 0; FFreeRTOSTimerTacho *instance = &os_timer_tacho[id]; - + + FTimerTachoCtrl *timer = &instance->ctrl; FASSERT(FT_COMPONENT_IS_READY != os_timer_tacho[id].ctrl.isready); FASSERT((instance->locker = xSemaphoreCreateMutex()) != NULL); - u64 cnttick = 0; - FTimerTachoCtrl *timer = &instance->ctrl; - timercfg.id = id; - timercfg.cyc_cmp = timer_mode; + FTimerTachoConfig *timercfg = &timer->config; + memset(timer, 0, sizeof(timer)); + /* tacho */ + FTimerGetDefConfig(id, timercfg); + timercfg->id = id; + timercfg->cmp_type = timer_mode; + timercfg->timer_mode = FTIMER_RESTART; + cnttick = US2TICKS(times); FTIMER_OS_INFO("\n***cnttick:%llu.", cnttick); if (cnttick > 0xffffffff) { - timercfg.bits32 = FALSE; - timercfg.startcnt = MAX_64_VAL - cnttick; + timercfg->timer_bits = FTIMER_64_BITS; + startcnt = MAX_64_VAL - cnttick; + } + else + { + timercfg->timer_bits = FTIMER_32_BITS; + startcnt = MAX_32_VAL - cnttick; + } + ret = FTimerInit(timer, timercfg); + + if (timercfg->timer_bits == FTIMER_32_BITS) + { + ret |= FTimerSetPeriod32(timer, MAX_32_VAL); } else { - timercfg.bits32 = TRUE; - timercfg.startcnt = MAX_32_VAL - cnttick; + ret |= FTimerSetPeriod64(timer, MAX_64_VAL); } - /* Set CmpTick max value ,that we can easy to trigger RolloverIntr. */ - timercfg.cmptick32 = MAX_32_VAL; - timercfg.cmptick64 = MAX_64_VAL; - if (FREERTOS_TIMER_TACHO_SUCCESS != FTimerCfgInit(&timercfg, timer)) + + /*将时间参数us装换成计时器的ticks,我们设置StartTick,将CmpTick设置为最大*/ + ret = FTimerSetStartVal(timer,startcnt); + if (FREERTOS_TIMER_TACHO_SUCCESS != ret) { - FTIMER_OS_ERROR("Timer config init failed."); return NULL; } + FTIMER_OS_INFO("Timer Init finished."); + return (&os_timer_tacho[id]); } @@ -232,7 +153,6 @@ FError FFreeRTOSTimerStart(FFreeRTOSTimerTacho *os_timer_p) return ret; } - /** * @name: FFreeRTOSTimerStop * @msg: @@ -291,92 +211,6 @@ void FFreeRTOSTimerDebug(FFreeRTOSTimerTacho *os_timer_p) /***********************************************tacho******************************************************/ /**********************************************************************************************************/ -/** - * @name: FTachoCfgInit - * @msg: 添加配置 - * @return {*} - * @param {FFreeRTOSTachoConfigs} *tachocfg_p - * @param {FTimerTachoCtrl} *tacho - */ -static FError FTachoCfgInit(const FFreeRTOSTachoConfigs *tachocfg_p, FTimerTachoCtrl *tacho) -{ - FASSERT(tachocfg_p); - FASSERT(tacho); - FError ret = FREERTOS_TIMER_TACHO_SUCCESS; - - FTimerTachoConfig *pconfig = &tacho->config; - memset(tacho, 0, sizeof(tacho)); - /* tacho */ - FTachoGetDefConfig(tachocfg_p->id, pconfig); - - if (tachocfg_p->work_mode == FTIMER_WORK_MODE_TACHO) - { - pconfig->work_mode = FTIMER_WORK_MODE_TACHO; - - if (tachocfg_p->bits32 == FTIMER_32_BITS) - { - pconfig->timer_bits = FTIMER_32_BITS; - } - else - { - pconfig->timer_bits = FTIMER_64_BITS; - } - - if (tachocfg_p->restart_mode) - { - pconfig->timer_mode = FTIMER_RESTART; - } - else - { - pconfig->timer_mode = FTIMER_FREE_RUN; - } - } - else - { - pconfig->work_mode = FTIMER_WORK_MODE_CAPTURE; - pconfig->captue_cnt = 0x7f;/* 边沿检测计数默认值 */ - } - - if (tachocfg_p->edge_mode == FTACHO_RISING_EDGE) - { - pconfig->edge_mode = FTACHO_RISING_EDGE; - } - else if (tachocfg_p->edge_mode == FTACHO_FALLING_EDGE) - { - pconfig->edge_mode = FTACHO_FALLING_EDGE; - } - else - { - pconfig->edge_mode = FTACHO_DOUBLE_EDGE; - } - - switch (tachocfg_p->jitter_level) - { - case FTACHO_JITTER_LEVEL0: - pconfig->jitter_level = FTACHO_JITTER_LEVEL0; - break; - case FTACHO_JITTER_LEVEL1: - pconfig->jitter_level = FTACHO_JITTER_LEVEL1; - break; - case FTACHO_JITTER_LEVEL2: - pconfig->jitter_level = FTACHO_JITTER_LEVEL2; - break; - case FTACHO_JITTER_LEVEL3: - pconfig->jitter_level = FTACHO_JITTER_LEVEL3; - break; - default: - pconfig->jitter_level = FTACHO_JITTER_LEVEL0; - break; - } - - if (tachocfg_p->plus_num != 0) - { - pconfig->plus_num = tachocfg_p->plus_num; - } - - ret = FTachoInit(tacho, pconfig); -} - /** * @name: FFreeRTOSTachoInit * @msg: tacho or capture init function @@ -392,37 +226,30 @@ FFreeRTOSTimerTacho *FFreeRTOSTachoInit(u32 id, boolean tacho_mode) FFreeRTOSTimerTacho *instance = &os_timer_tacho[id]; FTimerTachoCtrl *tacho = &os_timer_tacho[id].ctrl; + FTimerTachoConfig *tachocfg = &tacho->config; + memset(tacho, 0, sizeof(tacho)); + /* tacho */ + FTachoGetDefConfig(id, tachocfg); + FASSERT((instance->locker = xSemaphoreCreateMutex()) != NULL); FError ret = FREERTOS_TIMER_TACHO_SUCCESS; - tachocfg.id = id; - tachocfg.edge_mode = FTACHO_RISING_EDGE;/* Not open operation interface for cmd */ - tachocfg.jitter_level = FTACHO_JITTER_LEVEL0;/* Not open operation interface for cmd */ - tachocfg.bits32 = FTIMER_32_BITS;/* Use capture mode, Not open operation interface for cmd.*/ - tachocfg.restart_mode = FTIMER_RESTART;/* Use capture mode, Not open operation interface for cmd.*/ - tachocfg.plus_num = TACHO_PERIOD; - if (tacho_mode == FTIMER_WORK_MODE_TACHO) - { - tachocfg.work_mode = FTIMER_WORK_MODE_TACHO; - } - else - { - tachocfg.work_mode = FTIMER_WORK_MODE_CAPTURE; - } - - ret = FTachoCfgInit(&tachocfg, tacho); - if (ret != FREERTOS_TIMER_TACHO_SUCCESS) - { - FTACHO_OS_ERROR("Tacho config init failed."); - return NULL; - } + tachocfg->id = id; + tachocfg->work_mode = FTIMER_WORK_MODE_TACHO; + tachocfg->edge_mode = FTACHO_RISING_EDGE;/* Not open operation interface for cmd */ + tachocfg->jitter_level = FTACHO_JITTER_LEVEL0;/* Not open operation interface for cmd */ + tachocfg->timer_bits = FTIMER_32_BITS;/* Use capture mode, Not open operation interface for cmd.*/ + tachocfg->timer_mode = FTIMER_RESTART;/* Use capture mode, Not open operation interface for cmd.*/ + tachocfg->plus_num = TACHO_PERIOD; if (tacho_mode == FTIMER_WORK_MODE_TACHO) { /* Not open operation interface for cmd */ FTachoSetOverLimit(tacho, TACHO_MAX); FTachoSetUnderLimit(tacho, TACHO_MIN); + tachocfg->captue_cnt = 0x7f;/* 边沿检测计数默认值 */ } + ret = FTachoInit(tacho, tachocfg); return (&os_timer_tacho[id]); } diff --git a/drivers/wdt/fwdt_os.c b/drivers/wdt/fwdt_os.c index b05955b21354f4fe8986cbe1afb79e3a4247e1d1..38adae4db9949f0412fe7371ff112f81f1725352 100644 --- a/drivers/wdt/fwdt_os.c +++ b/drivers/wdt/fwdt_os.c @@ -45,7 +45,7 @@ static FFreeRTOSWdt os_wdt[FWDT_NUM] = {0}; /** * @name: FFreeRTOSWdtInit - * @msg: init freeRTOS wdt instance, include init wdt and create mutex + * @msg: init FreeRTOS wdt instance, include init wdt and create mutex * @param {u32} instance_id, wdt instance id * @return {FFreeRTOSWdt *} pointer to os wdt instance */ @@ -66,7 +66,7 @@ FFreeRTOSWdt *FFreeRTOSWdtInit(u32 instance_id) /** * @name: FFreeRTOSWdtDeinit - * @msg: deinit freeRTOS wdt instance, include stop wdt, deinit wdt and delete mutex + * @msg: deinit FreeRTOS wdt instance, include stop wdt, deinit wdt and delete mutex * @param {FFreeRTOSWdt} *os_wdt_p, pointer to os wdt instance * @return err code information, FWDT_SUCCESS indicates success,others indicates failed */ @@ -84,7 +84,7 @@ FError FFreeRTOSWdtDeinit(FFreeRTOSWdt *os_wdt_p) /** * @name: FFreeRTOSWdtControl - * @msg: control freeRTOS wdt instance + * @msg: control FreeRTOS wdt instance * @param {FFreeRTOSWdt} *os_wdt_p, pointer to os wdt instance * @param {int} cmd, control cmd * @param {void} *args, pointer to control cmd arguments diff --git a/drivers/wdt/fwdt_os.h b/drivers/wdt/fwdt_os.h index be4cea01e47011632cc06da93e80611630386219..9f2bf0eec83525d6fa78bb2f7542a74fc27dfd67 100644 --- a/drivers/wdt/fwdt_os.h +++ b/drivers/wdt/fwdt_os.h @@ -38,6 +38,7 @@ extern "C" /* freertos wdt error */ #define FREERTOS_WDT_SEM_ERROR FT_CODE_ERR(ErrModBsp, ErrBspWdt, 10) +#define FREERTOS_WDT_INIT_ERROR FT_CODE_ERR(ErrModBsp, ErrBspWdt, 11) /* freertos wdt interrupt priority */ #define FREERTOS_WDT_IRQ_PRIORITY IRQ_PRIORITY_VALUE_12 diff --git a/example/freertos_feature/eventgroup/README.md b/example/freertos_feature/eventgroup/README.md index 42828e8572ed9ac96dd20ec0e85ecd37d709801b..40ac30028cecff1b432a263182026a2fb40939bb 100644 --- a/example/freertos_feature/eventgroup/README.md +++ b/example/freertos_feature/eventgroup/README.md @@ -9,7 +9,7 @@ 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -40,13 +40,13 @@ - CONFIG_USE_LETTER_SHELL 本例子已经提供好具体的编译指令,以下进行介绍: -- make 将目录下的工程进行编译 -- make clean 将目录下的工程进行清理 -- make image 将目录下的工程进行编译,并将生成的elf 复制到目标地址 -- make list_kconfig 当前工程支持哪些配置文件 -- make load_kconfig LOAD_CONFIG_NAME= 将预设配置加载至工程中 -- make menuconfig 配置目录下的参数变量 -- make backup_kconfig 将目录下的sdkconfig 备份到./configs下 +- make 将目录下的工程进行编译 +- make clean 将目录下的工程进行清理 +- make image 将目录下的工程进行编译,并将生成的elf 复制到目标地址 +- make list_kconfig 当前工程支持哪些配置文件 +- make load_kconfig LOAD_CONFIG_NAME= 将预设配置加载至工程中 +- make menuconfig 配置目录下的参数变量 +- make backup_kconfig 将目录下的sdkconfig 备份到./configs下 具体使用方法为: - 在当前目录下 @@ -77,14 +77,10 @@ bootelf -p 0x90100000 ### 2.4 输出与实验现象 - 系统进入后,输入```event```查看指令说明 -- 输入```event manage_cre```,启动Event Group管理测试 -- 输入```event manage_del```,删除Event Group管理测试 - +- 输入```event manage_example```,启动Event Group管理测试 ![manage](./figs/event_manage.png) -- 输入```event sync_cre```,启动Event Group任务同步测试 -- 输入```event sync_del```,删除Event Group任务同步测试 - +- 输入```event sync_example```,启动Event Group任务同步测试 ![sync](./figs/event_sync.png) - 测试任务能够能正常创建和删除,输入```ps```查看任务状态正常,即测试正常 diff --git a/example/freertos_feature/eventgroup/figs/event_manage.png b/example/freertos_feature/eventgroup/figs/event_manage.png index bb6e731973490f77a9ac7894fbf3e40729630ac9..1340067b90404f8898a7f5caf2c7a569a5cc8254 100644 Binary files a/example/freertos_feature/eventgroup/figs/event_manage.png and b/example/freertos_feature/eventgroup/figs/event_manage.png differ diff --git a/example/freertos_feature/eventgroup/figs/event_sync.png b/example/freertos_feature/eventgroup/figs/event_sync.png index 5e1b24083c5ee925261c39da02cf955aa49f2128..4db43eca2a25b6eff7afd93a664bd67fd73b8b2a 100644 Binary files a/example/freertos_feature/eventgroup/figs/event_sync.png and b/example/freertos_feature/eventgroup/figs/event_sync.png differ diff --git a/example/freertos_feature/eventgroup/inc/feature_eventgroup.h b/example/freertos_feature/eventgroup/inc/feature_eventgroup.h index 300d1dc22da8991ba5dea8d8927efb9e5f1e66e0..cb1e5627861a054ee16d828253c494c64fe8c644 100644 --- a/example/freertos_feature/eventgroup/inc/feature_eventgroup.h +++ b/example/freertos_feature/eventgroup/inc/feature_eventgroup.h @@ -17,9 +17,10 @@ * Description: This file is for task function define * * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - * 1.0 wangxiaodong 2022/08/09 first commit + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first commit + * 2.0 liqiaozhong 2024/5/6 add no letter shell mode, adapt to auto-test system */ @@ -32,12 +33,10 @@ extern "C" #endif /* event group Management task */ -void CreateManagementTasks(void); -void DeleteManagementTasks(void); +int CreateManagementTasks(void); /* event group Synchronization task */ -void CreateSyncTasks(void); -void DeleteSyncTasks(void); +int CreateSyncTasks(void); #ifdef __cplusplus } diff --git a/example/freertos_feature/eventgroup/main.c b/example/freertos_feature/eventgroup/main.c index fa9cccdffe6808a34d07fbffcc6faba76dfd6398..e9800659f6f9324c14c6443231a767488a8e01af 100644 --- a/example/freertos_feature/eventgroup/main.c +++ b/example/freertos_feature/eventgroup/main.c @@ -17,20 +17,49 @@ * Description: This file is for eventgroup example that running shell task and open scheduler * * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - * 1.0 wangxiaodong 2022/08/09 first commit + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first commit + * 2.0 liqiaozhong 2024/5/6 add no letter shell mode, adapt to auto-test system */ +#include + +#include "FreeRTOS.h" + +#include "sdkconfig.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include +#else +#include "task.h" +#include "feature_eventgroup.h" +#define EVENTGROUP_EXAMPLE_TASK_PRIORITY 2 +void EventgroupExampleTaskEntry() +{ + CreateManagementTasks(); + CreateSyncTasks(); + + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif int main(void) { - BaseType_t ret; - - ret = LSUserShellTask() ; + BaseType_t ret = pdPASS; /* Define a return value with a default of pdPASS */ +#ifdef CONFIG_USE_LETTER_SHELL + ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)EventgroupExampleTaskEntry, + (const char *)"EventgroupExampleTaskEntry", + (uint16_t)4096, + NULL, + (UBaseType_t)EVENTGROUP_EXAMPLE_TASK_PRIORITY, + NULL); +#endif if (ret != pdPASS) { goto FAIL_EXIT; @@ -40,6 +69,6 @@ int main(void) while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("Failed 0x%x. \r\n", ret); - return 0; -} + printf("Event group example failed in main.c, the ret value is 0x%x. \r\n", ret); + return -2; +} \ No newline at end of file diff --git a/example/freertos_feature/eventgroup/src/eventgroup_cmd.c b/example/freertos_feature/eventgroup/src/eventgroup_cmd.c index 173ee67bebacd0ea7a7656fc93db21cfff9d2ffc..212a8fadab1f9aa97b5b506f840434de2b0ea058 100644 --- a/example/freertos_feature/eventgroup/src/eventgroup_cmd.c +++ b/example/freertos_feature/eventgroup/src/eventgroup_cmd.c @@ -17,40 +17,34 @@ * Description: This file is for eventgroup command interface * * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - * 1.0 wangxiaodong 2022/08/09 first commit + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first commit + * 2.0 liqiaozhong 2024/5/6 add no letter shell mode, adapt to auto-test system */ -#include "shell.h" #include #include -#include "feature_eventgroup.h" -typedef enum -{ - MANAGE_TASK_INDEX = 0, - SYNC_TASK_INDEX = 1, - EVENTGROUP_FEATURE_LENGTH -} FreeRtosEventgroupFeatureSelect; +#include "sdkconfig.h" + +#ifdef CONFIG_USE_LETTER_SHELL +#include "../src/shell.h" + +#include "feature_eventgroup.h" static void EventTasksCmdUsage(void) { - printf("Usage:\r\n"); - printf(" event manage_cre \r\n"); - printf(" -- Create manage tasks now.\r\n"); - printf(" event manage_del \r\n"); - printf(" -- Del manage tasks now.\r\n"); - printf(" event sync_cre \r\n"); - printf(" -- Create sync tasks now.\r\n"); - printf(" event sync_del \r\n"); - printf(" -- Del sync tasks now.\r\n"); - + printf("Usage: \r\n"); + printf("event manage_example \r\n"); + printf("-- Create manage tasks. \r\n"); + printf("event sync_example \r\n"); + printf("-- Create sync tasks. \r\n"); } int CreateEventCmd(int argc, char *argv[]) { - static int create_flg[EVENTGROUP_FEATURE_LENGTH] = {0}; /* 1 is tasks has been created*/ + int ret = 0; if (argc < 2) { @@ -58,62 +52,22 @@ int CreateEventCmd(int argc, char *argv[]) return -1; } - if (!strcmp(argv[1], "manage_cre")) + if (!strcmp(argv[1], "manage_example")) { - if (create_flg[MANAGE_TASK_INDEX] == 0) - { - CreateManagementTasks(); - create_flg[MANAGE_TASK_INDEX] = 1; - } - else - { - printf("Please use manage_del cmd first. \r\n"); - } + ret = CreateManagementTasks(); } - else if (!strcmp(argv[1], "manage_del")) + else if (!strcmp(argv[1], "sync_example")) { - if (create_flg[MANAGE_TASK_INDEX] == 1) - { - DeleteManagementTasks(); - create_flg[MANAGE_TASK_INDEX] = 0; - } - else - { - printf("Please use manage_cre cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "sync_cre")) - { - if (create_flg[SYNC_TASK_INDEX] == 0) - { - CreateSyncTasks(); - create_flg[SYNC_TASK_INDEX] = 1; - } - else - { - printf("Please use sync_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "sync_del")) - { - if (create_flg[SYNC_TASK_INDEX] == 1) - { - DeleteSyncTasks(); - create_flg[SYNC_TASK_INDEX] = 0; - } - else - { - printf("Please use sync_cre cmd first. \r\n"); - } + ret = CreateSyncTasks(); } else { printf("Error: Invalid arguments. \r\n"); EventTasksCmdUsage(); } - return 0; + + return ret; } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), event, CreateEventCmd, event group creating test); - - +#endif \ No newline at end of file diff --git a/example/freertos_feature/eventgroup/src/management.c b/example/freertos_feature/eventgroup/src/management.c index 0c4491eff705148ea660f618fae744962ef08a0a..04e6702614794f23b737c5c97f735c053929bec7 100644 --- a/example/freertos_feature/eventgroup/src/management.c +++ b/example/freertos_feature/eventgroup/src/management.c @@ -1,260 +1,304 @@ -/* -This example demonstrates how to: - Create an event group. - Set bits in an event group from an interrupt service routine. - Set bits in an event group from a task. - Block on an event group. -*/ +/* This example demonstrates how to: + Create an event group. + Set bits in an event group from an interrupt service routine. + Set bits in an event group from a task. + Block on an event group. + */ #include "FreeRTOS.h" #include "task.h" #include "event_groups.h" +#include "queue.h" #include "timers.h" /* For the xTimerPendFunctionCallFromISR() function. */ + #include "finterrupt.h" #include "fcpu_info.h" -static xTaskHandle xtask1_handle; -static xTaskHandle xtask2_handle; -static xTaskHandle xtask3_handle; - -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 +#define TASK_PRIORITY 3 +#define EVENT_SEND_TIMES 2 +#define EVENTGROUP_MANAGEMENT_TIMEOUT pdMS_TO_TICKS(30000U) +#define WAIT_BITS_TIMEOUT pdMS_TO_TICKS(10000U) -/* The interrupt number to use for the software interrupt generation. This -could be any unused number. In this case the first chip level (non system) -interrupt is used */ -#define INTERRUPT_ID 0 +/* The interrupt number to use for the software interrupt generation. + * Thiscould be any unused number. + * In this case, the first chip level (non system) interrupt is used. + */ +#define INTERRUPT_ID 0 -/* The priority of the software interrupt. The interrupt service routine uses -an (interrupt safe) FreeRTOS API function, so the priority of the interrupt must -be equal to or lower than the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY. */ -#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +/* The priority of the software interrupt. + * The interrupt service routine uses an (interrupt safe) FreeRTOS API function, + so the priority of the interrupt must be equal to or lower than the priority set by configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 /* Definitions for the event bits in the event group. */ -#define FIRST_TASK_BIT ( 1UL << 0UL ) /* Event bit 0, which is set by a task. */ -#define SECOND_TASK_BIT ( 1UL << 1UL ) /* Event bit 1, which is set by a task. */ -#define ISR_BIT ( 1UL << 2UL ) /* Event bit 2, which is set by an ISR. */ +#define FIRST_TASK_BIT (1UL << 0UL) /* Event bit 0, which is set by a task. */ +#define SECOND_TASK_BIT (1UL << 1UL) /* Event bit 1, which is set by a task. */ +#define ISR_BIT (1UL << 2UL) /* Event bit 2, which is set by an ISR. */ + +enum +{ + EXAMPLE_SUCCESS = 0, + EXAMPLE_UNKNOWN_STATE, + EXAMPLE_FAILURE, +}; + +static EventGroupHandle_t xEventGroup; /* Declare the event group in which bits are set from both a task and an ISR. */ +static QueueHandle_t xQueue = NULL; +static u32 cpu_id = 0; /* The tasks to be created. */ static void vIntegerGenerator(void *pvParameters); static void vEventBitSettingTask(void *pvParameters); static void vEventBitReadingTask(void *pvParameters); -/* A function that can be deferred to run in the RTOS daemon task. The function -prints out the string passed to it using the pvParameter1 parameter. */ +/* A function that can be deferred to run in the RTOS daemon task. + * The function prints out the string passed to it using the pvParameter1 parameter. + */ void vPrintStringFromDaemonTask(void *pvParameter1, uint32_t ulParameter2); -/* The service routine for the (simulated) interrupt. This is the interrupt -that sets an event bit in the event group. */ +/* The service routine for the (simulated) interrupt. + * This is the interrupt that sets an event bit in the event group. + */ static void vSetupSoftwareInterrupt(void); /* Macro to force an interrupt. */ static void vTriggerInterrupt(void); -static u32 cpu_id = 0; - /*-----------------------------------------------------------*/ -/* Declare the event group in which bits are set from both a task and an ISR. */ -static EventGroupHandle_t xEventGroup; +void vPrintStringFromDaemonTask(void *pvParameter1, uint32_t ulParameter2) +{ + /* The string to print is passed into this function using the pvParameter1 parameter. */ + vPrintString((const char *) pvParameter1); +} + +/*-----------------------------------------------------------*/ -void CreateManagementTasks(void) +static void ulEventBitSettingISR(s32 vector, void *param) { - /* Before an event group can be used it must first be created. */ - xEventGroup = xEventGroupCreate(); - vSetupSoftwareInterrupt(); + BaseType_t xHigherPriorityTaskWoken; + /* The string is not printed within the interrupt service, but is instead sent to the RTOS daemon task for printing. + * It is therefore declared static to ensure the compiler does not allocate the string on the stack of the ISR as the + ISR's stack frame will not exist when the string is printed from the daemon task. + */ + static const char *pcString = "Manage Bit setting ISR -\t about to set bit 2."; - /* Create the task that sets event bits in the event group. */ - xTaskCreate(vEventBitSettingTask, "Manage BitSetter", TASK_STACK_SIZE, NULL, 1, &xtask1_handle); + /* As always, xHigherPriorityTaskWoken is initialized to pdFALSE. */ + xHigherPriorityTaskWoken = pdFALSE; + + /* Print out a message to say bit 2 is about to be set. + * Messages cannot be printed from an ISR, so defer the actual output to the RTOS daemon task by + pending a function call to run in the context of the RTOS daemon task. + */ + xTimerPendFunctionCallFromISR(vPrintStringFromDaemonTask, (void *)pcString, 0, &xHigherPriorityTaskWoken); + + /* Set bit 2 in the event group. */ + xEventGroupSetBitsFromISR(xEventGroup, ISR_BIT, &xHigherPriorityTaskWoken); - /* Create the task that waits for event bits to get set in the event - group. */ - xTaskCreate(vEventBitReadingTask, "Manage BitReader", TASK_STACK_SIZE, NULL, 2, &xtask2_handle); + /* xEventGroupSetBitsFromISR() writes to the timer command queue. + * If writing to the timer command queue results in the RTOS daemon task leaving the Blocked state, + and if the priority of the RTOS daemon task is higher than the priority of the currently executing task + (the task this interrupt interrupted) then xHigherPriorityTaskWoken will have been set to pdTRUE inside xEventGroupSetBitsFromISR(). - /* Create the task that is used to periodically generate a software - interrupt. */ - xTaskCreate(vIntegerGenerator, "Manage IntGen", TASK_STACK_SIZE, NULL, 3, &xtask3_handle); + * xHigherPriorityTaskWoken is used as the parameter to portYIELD_FROM_ISR(). + * If xHigherPriorityTaskWoken equals pdTRUE then calling portYIELD_FROM_ISR() will request a context switch. + * If xHigherPriorityTaskWoken is still pdFALSE then calling portYIELD_FROM_ISR() will have no effect. - /* Install the handler for the software interrupt. The syntax necessary - to do this is dependent on the FreeRTOS port being used. */ + * The implementation of portYIELD_FROM_ISR() used by the Windows port includes a return statement, + which is why this function does not explicitly return a value. + */ + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } -void DeleteManagementTasks(void) +/*-----------------------------------------------------------*/ + +static void vSetupSoftwareInterrupt(void) { - if (xtask1_handle) - { - vTaskDelete(xtask1_handle); - vPrintString("Eventgroup management BitSetter deletion"); - } - if (xtask2_handle) - { - vTaskDelete(xtask2_handle); - vPrintString("Eventgroup management BitReader deletion"); - } + GetCpuId(&cpu_id); - if (xtask3_handle) - { - vTaskDelete(xtask3_handle); - vPrintString("Eventgroup management IntGen deletion"); - } + /* The interrupt service routine uses an (interrupt safe) FreeRTOS API function so the interrupt priority + must be at or below the priority defined by configSYSCALL_INTERRUPT_PRIORITY. + */ + InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY); + + InterruptInstall(INTERRUPT_ID, ulEventBitSettingISR, NULL, NULL); + /* Enable the interrupt. */ + InterruptUmask(INTERRUPT_ID); } + /*-----------------------------------------------------------*/ static void vEventBitSettingTask(void *pvParameters) { - const TickType_t xDelay = pdMS_TO_TICKS(5000UL), xDontBlock = 0; + const TickType_t xDelay = pdMS_TO_TICKS(2000UL); - for (;;) + for (int loop = 0; loop < EVENT_SEND_TIMES; loop++) { /* Delay for a short while before starting the next loop. */ vTaskDelay(xDelay); - /* Print out a message to say event bit 0 is about to be set by the - task, then set event bit 0. */ + /* Print out a message to say event bit 0 is about to be set by the task, then set event bit 0. */ vPrintString("Manage Bit setting task -\t about to set bit 0."); xEventGroupSetBits(xEventGroup, FIRST_TASK_BIT); - /* Delay for a short while before setting the other bit set within this - task. */ + /* Delay for a short while before setting the other bit set within this task. */ vTaskDelay(xDelay); - /* Print out a message to say event bit 1 is about to be set by the - task, then set event bit 1. */ + /* Print out a message to say event bit 1 is about to be set by the task, then set event bit 1. */ vPrintString("Manage Bit setting task -\t about to set bit 1."); xEventGroupSetBits(xEventGroup, SECOND_TASK_BIT); } + + vPrintString("Eventgroup management BitSetter deletion"); + vTaskDelete(NULL); } + /*-----------------------------------------------------------*/ -static void ulEventBitSettingISR(s32 vector, void *param) +/* Macro to force an interrupt. */ +static void vTriggerInterrupt(void) { - BaseType_t xHigherPriorityTaskWoken; - /* The string is not printed within the interrupt service, but is instead - sent to the RTOS daemon task for printing. It is therefore declared static to - ensure the compiler does not allocate the string on the stack of the ISR (as the - ISR's stack frame will not exist when the string is printed from the daemon - task. */ - static const char *pcString = "Manage Bit setting ISR -\t about to set bit 2."; + InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); +} - /* As always, xHigherPriorityTaskWoken is initialized to pdFALSE. */ - xHigherPriorityTaskWoken = pdFALSE; +/*-----------------------------------------------------------*/ - /* Print out a message to say bit 2 is about to be set. Messages cannot be - printed from an ISR, so defer the actual output to the RTOS daemon task by - pending a function call to run in the context of the RTOS daemon task. */ - xTimerPendFunctionCallFromISR(vPrintStringFromDaemonTask, (void *) pcString, 0, &xHigherPriorityTaskWoken); +static void vIntegerGenerator(void *pvParameters) +{ + TickType_t xLastExecutionTime; + const TickType_t xDelay = pdMS_TO_TICKS(5000UL); - /* Set bit 2 in the event group. */ - xEventGroupSetBitsFromISR(xEventGroup, ISR_BIT, &xHigherPriorityTaskWoken); + /* Initialize the variable used by the call to vTaskDelayUntil(). */ + xLastExecutionTime = xTaskGetTickCount(); - /* xEventGroupSetBitsFromISR() writes to the timer command queue. If - writing to the timer command queue results in the RTOS daemon task leaving - the Blocked state, and if the priority of the RTOS daemon task is higher - than the priority of the currently executing task (the task this interrupt - interrupted) then xHigherPriorityTaskWoken will have been set to pdTRUE - inside xEventGroupSetBitsFromISR(). - - xHigherPriorityTaskWoken is used as the parameter to portYIELD_FROM_ISR(). - If xHigherPriorityTaskWoken equals pdTRUE then calling portYIELD_FROM_ISR() - will request a context switch. If xHigherPriorityTaskWoken is still pdFALSE - then calling portYIELD_FROM_ISR() will have no effect. - - The implementation of portYIELD_FROM_ISR() used by the Windows port includes - a return statement, which is why this function does not explicitly return a - value. */ - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + for (int loop = 0; loop < EVENT_SEND_TIMES; loop++) + { + /* This is a periodic task. + * Block until it is time to run again. + * The task will execute every 500ms. + */ + vTaskDelayUntil(&xLastExecutionTime, xDelay); + + /* Generate the interrupt that will set a bit in the event group. */ + vTriggerInterrupt(); + } + + vPrintString("Eventgroup management IntGen deletion"); + vTaskDelete(NULL); } + /*-----------------------------------------------------------*/ static void vEventBitReadingTask(void *pvParameters) { const EventBits_t xBitsToWaitFor = (FIRST_TASK_BIT | SECOND_TASK_BIT | ISR_BIT); EventBits_t xEventGroupValue; + int task_res = EXAMPLE_SUCCESS; + + int first_bit_count = 0; + int second_bit_count = 0; + int isr_bit_count = 0; for (;;) { /* Block to wait for event bits to become set within the event group. */ - xEventGroupValue = xEventGroupWaitBits( /* The event group to read. */ - xEventGroup, - - /* Bits to test. */ - xBitsToWaitFor, - - /* Clear bits on exit if the - unblock condition is met. */ - pdTRUE, - - /* Don't wait for all bits. */ - pdFALSE, - - /* Don't time out. */ - portMAX_DELAY); + xEventGroupValue = xEventGroupWaitBits(xEventGroup, /* The event group to read. */ + xBitsToWaitFor, /* Bits to test. */ + pdTRUE, /* Clear bits on exit if the unblock condition is met. */ + pdFALSE, /* Don't wait for all bits. */ + WAIT_BITS_TIMEOUT); /* Print a message for each bit that was set. */ if ((xEventGroupValue & FIRST_TASK_BIT) != 0) { vPrintString("Manage Bit reading task -\t event bit 0 was set"); + first_bit_count ++; } - - if ((xEventGroupValue & SECOND_TASK_BIT) != 0) + else if ((xEventGroupValue & SECOND_TASK_BIT) != 0) { vPrintString("Manage Bit reading task -\t event bit 1 was set"); + second_bit_count ++; } - - if ((xEventGroupValue & ISR_BIT) != 0) + else if ((xEventGroupValue & ISR_BIT) != 0) { vPrintString("Manage Bit reading task -\t event bit 2 was set"); + isr_bit_count ++; + } + else + { + vPrintString("xEventGroupWaitBits timeout."); + task_res = EXAMPLE_FAILURE; + goto bit_reader_exit; + } + + if ((first_bit_count >= EVENT_SEND_TIMES) && (second_bit_count >= EVENT_SEND_TIMES) && (isr_bit_count >= EVENT_SEND_TIMES)) + { + goto bit_reader_exit; } } -} -/*-----------------------------------------------------------*/ -void vPrintStringFromDaemonTask(void *pvParameter1, uint32_t ulParameter2) -{ - /* The string to print is passed into this function using the pvParameter1 - parameter. */ - vPrintString((const char *) pvParameter1); +bit_reader_exit: + vPrintString("Eventgroup management BitReader deletion"); + xQueueSend(xQueue, &task_res, 0); + vTaskDelete(NULL); } + /*-----------------------------------------------------------*/ -static void vIntegerGenerator(void *pvParameters) +int CreateManagementTasks(void) { - TickType_t xLastExecutionTime; - const TickType_t xDelay = pdMS_TO_TICKS(5000UL); - - /* Initialize the variable used by the call to vTaskDelayUntil(). */ - xLastExecutionTime = xTaskGetTickCount(); + BaseType_t xReturn = pdPASS; /* Define a return value with a default of pdPASS */ + int task_res = EXAMPLE_UNKNOWN_STATE; - for (;;) + xQueue = xQueueCreate(1, sizeof(int)); /* create Message Queue */ + if (xQueue == NULL) { - /* This is a periodic task. Block until it is time to run again. - The task will execute every 500ms. */ - vTaskDelayUntil(&xLastExecutionTime, xDelay); - - /* Generate the interrupt that will set a bit in the event group. */ - vTriggerInterrupt(); + vPrintString("xQueue create failed."); + goto exit; } -} -static void vSetupSoftwareInterrupt(void) -{ + /* Before an event group can be used it must first be created. */ + xEventGroup = xEventGroupCreate(); - GetCpuId(&cpu_id); - vPrintf("cpu_id is %d \r\n", cpu_id); + /* Install the handler for the software interrupt. + * The syntax necessary to do this is dependent on the FreeRTOS port being used. + */ + vSetupSoftwareInterrupt(); - /* The interrupt service routine uses an (interrupt safe) FreeRTOS API - function so the interrupt priority must be at or below the priority defined - by configSYSCALL_INTERRUPT_PRIORITY. */ - InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY); + /* Create the task that sets event bits in the event group. */ + xTaskCreate(vEventBitSettingTask, "Manage BitSetter", TASK_STACK_SIZE, NULL, TASK_PRIORITY, NULL); - InterruptInstall(INTERRUPT_ID, ulEventBitSettingISR, NULL, NULL); + /* Create the task that is used to periodically generate a software interrupt. */ + xTaskCreate(vIntegerGenerator, "Manage IntGen", TASK_STACK_SIZE, NULL, TASK_PRIORITY, NULL); - /* Enable the interrupt. */ - InterruptUmask(INTERRUPT_ID); -} + /* Create the task that waits for event bits to get set in the event group. */ + xTaskCreate(vEventBitReadingTask, "Manage BitReader", TASK_STACK_SIZE, NULL, TASK_PRIORITY, NULL); -/* Macro to force an interrupt. */ -static void vTriggerInterrupt(void) -{ - InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); -} + + xReturn = xQueueReceive(xQueue, &task_res, EVENTGROUP_MANAGEMENT_TIMEOUT); + if (xReturn == pdFAIL) + { + vPrintString("xQueue receive timeout."); + goto exit; + } + +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } + + if (task_res != EXAMPLE_SUCCESS) + { + vPrintString("Event group feature management example [failure]"); + return task_res; + } + else + { + vPrintString("Event group feature management example [success]."); + return task_res; + } +} \ No newline at end of file diff --git a/example/freertos_feature/eventgroup/src/synchronization.c b/example/freertos_feature/eventgroup/src/synchronization.c index 6d2afbac4a570b3b3947b0de509891a939f21fe7..558486e21101f794eab155344dc5411e78bab83f 100644 --- a/example/freertos_feature/eventgroup/src/synchronization.c +++ b/example/freertos_feature/eventgroup/src/synchronization.c @@ -1,34 +1,34 @@ -/* -This example demonstrates how to: -uses xEventGroupSync() to synchronize three instances of a single task implementation. -The task parameter is used to pass into each instance the event bit the task will -set when it calls xEventGroupSync(). -*/ +/* This example demonstrates how to: + uses xEventGroupSync() to synchronize three instances of a single task implementation. + * The task parameter is used to pass into each instance the event bit the task will set when it calls xEventGroupSync(). + */ #include #include "FreeRTOS.h" #include "task.h" +#include "queue.h" #include "event_groups.h" -static xTaskHandle xtask1_handle; -static xTaskHandle xtask2_handle; -static xTaskHandle xtask3_handle; +#define TASK_STACK_SIZE 1024 +#define TASK_PRIORITY 3 +#define SYNCHRONIZATION_TASK_NUM 3 +#define WAIT_BITS_TIMEOUT pdMS_TO_TICKS(10000U) +#define EXAMPLE_TIMEOUT pdMS_TO_TICKS(30000U) -#define TASK_STACK_SIZE 1024 /* Definitions for the event bits in the event group. */ -#define FIRST_TASK_BIT ( 1UL << 0UL ) /* Event bit 0, which is set by the first task. */ -#define SECOND_TASK_BIT ( 1UL << 1UL ) /* Event bit 1, which is set by the second task. */ -#define THIRD_TASK_BIT ( 1UL << 2UL ) /* Event bit 2, which is set by the third task. */ +#define FIRST_TASK_BIT (1UL << 0UL) /* Event bit 0, which is set by the first task. */ +#define SECOND_TASK_BIT (1UL << 1UL) /* Event bit 1, which is set by the second task. */ +#define THIRD_TASK_BIT (1UL << 2UL) /* Event bit 2, which is set by the third task. */ +#define TASK_ERROR_BIT (1UL << 3UL) /* Bit 3, which means sync task failed. */ +#define ALL_SYNC_BITS (FIRST_TASK_BIT | SECOND_TASK_BIT | THIRD_TASK_BIT) -/* Pseudo random number generation functions - implemented in this file as the -MSVC rand() function has unexpected consequences. */ -static uint32_t prvRand(void); -static void prvSRand(uint32_t ulSeed); +enum +{ + EVENTGROUP_SYNCHRONIZATION_SUCCESS = 0, + EVENTGROUP_SYNCHRONIZATION_UNKNOWN_STATE, +}; -/* Three instances of this task are created. */ -static void vSyncingTask(void *pvParameters); - -/*-----------------------------------------------------------*/ +static QueueHandle_t xQueue = NULL; /* Use by the pseudo random number generator. */ static uint32_t ulNextRand; @@ -36,124 +36,143 @@ static uint32_t ulNextRand; /* Declare the event group used to synchronize the three tasks. */ static EventGroupHandle_t xEventGroup; -void CreateSyncTasks(void) +/*-----------------------------------------------------------*/ +/* Pseudo random number generation functions - implemented in this file as the MSVC rand() function has unexpected consequences. */ +static uint32_t prvRand(void) { - /* The tasks created in this example block for a random time. The block - time is generated using rand() - seed the random number generator. */ - prvSRand((uint32_t) time(NULL)); - - /* Before an event group can be used it must first be created. */ - xEventGroup = xEventGroupCreate(); + const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL; + uint32_t ulReturn; - /* Create three instances of the task. Each task is given a different name, - which is later printed out to give a visual indication of which task is - executing. The event bit to use when the task reaches its synchronization - point is passed into the task using the task parameter. */ - xTaskCreate(vSyncingTask, "Sync Task 1", TASK_STACK_SIZE, (void *) FIRST_TASK_BIT, 1, &xtask1_handle); - xTaskCreate(vSyncingTask, "Sync Task 2", TASK_STACK_SIZE, (void *) SECOND_TASK_BIT, 1, &xtask2_handle); - xTaskCreate(vSyncingTask, "Sync Task 3", TASK_STACK_SIZE, (void *) THIRD_TASK_BIT, 1, &xtask3_handle); + /* Utility function to generate a pseudo random number as the MSVC rand() function has unexpected consequences. */ + taskENTER_CRITICAL(); + ulNextRand = (ulMultiplier * ulNextRand) + ulIncrement; + ulReturn = (ulNextRand >> 16UL) & 0x7fffUL; + taskEXIT_CRITICAL(); + return ulReturn; } -void DeleteSyncTasks(void) +static void prvSRand(uint32_t ulSeed) { - if (xtask1_handle) - { - vTaskDelete(xtask1_handle); - vPrintString("Eventgroup Sync Task 1 deletion \r\n"); - } - - if (xtask2_handle) - { - vTaskDelete(xtask2_handle); - vPrintString("Eventgroup Sync Task 2 deletion \r\n"); - } - - if (xtask3_handle) - { - vTaskDelete(xtask3_handle); - vPrintString("Eventgroup Sync Task 3 deletion \r\n"); - } - + /* Utility function to seed the pseudo random number generator. */ + ulNextRand = ulSeed; } -/*-----------------------------------------------------------*/ +/*-----------------------------------------------------------*/ +/* Three instances of this task are created. */ static void vSyncingTask(void *pvParameters) { - const EventBits_t uxAllSyncBits = (FIRST_TASK_BIT | SECOND_TASK_BIT | THIRD_TASK_BIT); + const EventBits_t uxAllSyncBits = ALL_SYNC_BITS; const TickType_t xMaxDelay = pdMS_TO_TICKS(500UL); const TickType_t xMinDelay = pdMS_TO_TICKS(4000UL); TickType_t xDelayTime; EventBits_t uxThisTasksSyncBit; + EventBits_t uxReturn; + u32 task_res = 0; - /* Three instances of this task are created - each task uses a different - event bit in the synchronization. The event bit to use by this task - instance is passed into the task using the task's parameter. Store it in - the uxThisTasksSyncBit variable. */ + /* Three instances of this task are created - each task uses a different event bit in the synchronization. + * The event bit to use by this task instance is passed into the task using the task's parameter. + * Store it in the uxThisTasksSyncBit variable. + */ uxThisTasksSyncBit = (EventBits_t) pvParameters; - for (;;) + /* Simulate this task taking some time to perform an action by delaying for a pseudo random time. + * This prevents all three instances of this task from reaching the synchronization point at the same time, + and allows the example's behavior to be observed more easily. + */ + xDelayTime = (prvRand() % xMaxDelay) + xMinDelay; + vTaskDelay(xDelayTime); + + /* Print out a message to show this task has reached its synchronization point. + * pcTaskGetTaskName() is an API function that returns the name assigned to the task when the task was created. + */ + vPrintString(pcTaskGetTaskName(NULL)); + vPrintString(" reached sync point"); + + /* Wait for all the tasks to have reached their respective synchronization points. */ + uxReturn = xEventGroupSync(xEventGroup, /* The event group used to synchronize. */ + uxThisTasksSyncBit, /* The bit set by this task to indicate it has reached the synchronization point. */ + uxAllSyncBits, /* The bits to wait for, one bit for each task taking part in the synchronization. */ + WAIT_BITS_TIMEOUT); /* Wait indefinitely for all three tasks to reach the synchronization point. */ + + /* Print out a message to show this task has passed its synchronization point. + * As an indefinite delay was used the following line will only be reached after all the tasks reached their respective synchronization points. + */ + if((uxReturn & uxAllSyncBits) == uxAllSyncBits) /* All three tasks reached the synchronisation point before the call to xEventGroupSync() timed out. */ { - /* Simulate this task taking some time to perform an action by delaying - for a pseudo random time. This prevents all three instances of this - task from reaching the synchronization point at the same time, and - allows the example's behavior to be observed more easily. */ - xDelayTime = (prvRand() % xMaxDelay) + xMinDelay; - vTaskDelay(xDelayTime); - - /* Print out a message to show this task has reached its synchronization - point. pcTaskGetTaskName() is an API function that returns the name - assigned to the task when the task was created. */ vPrintString(pcTaskGetTaskName(NULL)); - vPrintString(" reached sync point\n"); - - /* Wait for all the tasks to have reached their respective - synchronization points. */ - xEventGroupSync( /* The event group used to synchronize. */ - xEventGroup, - - /* The bit set by this task to indicate it has reached - the synchronization point. */ - uxThisTasksSyncBit, - - /* The bits to wait for, one bit for each task taking - part in the synchronization. */ - uxAllSyncBits, + vPrintString(" exited sync point"); - /* Wait indefinitely for all three tasks to reach the - synchronization point. */ - portMAX_DELAY); - - /* Print out a message to show this task has passed its synchronization - point. As an indefinite delay was used the following line will only be - reached after all the tasks reached their respective synchronization - points. */ vPrintString(pcTaskGetTaskName(NULL)); - vPrintString(" exited sync point\n"); + vPrintString(" deletion"); + task_res = uxThisTasksSyncBit; + xQueueSend(xQueue, &task_res, 0); + } + else + { + task_res = TASK_ERROR_BIT; + xQueueSend(xQueue, &task_res, 0); } + + vTaskDelete(NULL); } + /*-----------------------------------------------------------*/ -static uint32_t prvRand(void) +int CreateSyncTasks(void) { - const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL; - uint32_t ulReturn; + BaseType_t xReturn = pdPASS; /* Define a return value with a default of pdPASS */ + u32 task_res = 0; + u32 task_flag = 0; /* Flag for whether receive enough task_res */ - /* Utility function to generate a pseudo random number as the MSVC rand() - function has unexpected consequences. */ - taskENTER_CRITICAL(); - ulNextRand = (ulMultiplier * ulNextRand) + ulIncrement; - ulReturn = (ulNextRand >> 16UL) & 0x7fffUL; - taskEXIT_CRITICAL(); - return ulReturn; -} -/*-----------------------------------------------------------*/ + xQueue = xQueueCreate(3, sizeof(u32)); /* Creat Message Queue */ + if (xQueue == NULL) + { + vPrintString("xQueue create failed."); + goto exit; + } -static void prvSRand(uint32_t ulSeed) -{ - /* Utility function to seed the pseudo random number generator. */ - ulNextRand = ulSeed; -} -/*-----------------------------------------------------------*/ + /* The tasks created in this example block for a random time. + * The block time is generated using rand() - seed the random number generator. + */ + prvSRand((uint32_t) time(NULL)); + + /* Before an event group can be used it must first be created. */ + xEventGroup = xEventGroupCreate(); + /* Create three instances of the task. Each task is given a different name, + which is later printed out to give a visual indication of which task is executing. + * The event bit to use when the task reaches its synchronization point is passed into the task using the task parameter. + */ + xTaskCreate(vSyncingTask, "Sync Task 1", TASK_STACK_SIZE, (void *)FIRST_TASK_BIT, TASK_PRIORITY, NULL); + xTaskCreate(vSyncingTask, "Sync Task 2", TASK_STACK_SIZE, (void *)SECOND_TASK_BIT, TASK_PRIORITY, NULL); + xTaskCreate(vSyncingTask, "Sync Task 3", TASK_STACK_SIZE, (void *)THIRD_TASK_BIT, TASK_PRIORITY, NULL); + + for (int loop = 0; loop < SYNCHRONIZATION_TASK_NUM; loop++) + { + xReturn = xQueueReceive(xQueue, &task_res, EXAMPLE_TIMEOUT); + if (xReturn == pdFAIL || task_res == TASK_ERROR_BIT) + { + vPrintString("xQueue receive timeout or task err."); + goto exit; + } + task_flag |= task_res; + } + +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } + if (task_flag != ALL_SYNC_BITS) + { + vPrintf("Event group feature management example [failure], task_flag = 0x%x \r\n", task_flag); + return -1; + } + else + { + vPrintString("Event group feature management example [success]."); + return 0; + } +} \ No newline at end of file diff --git a/example/freertos_feature/interrupt/README.md b/example/freertos_feature/interrupt/README.md index 9244d8b18d615bd00559148f567e36a579728bac..1066e35530fc6ede7e7ea1974bc0bbdb29c4decc 100644 --- a/example/freertos_feature/interrupt/README.md +++ b/example/freertos_feature/interrupt/README.md @@ -9,7 +9,7 @@ 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/E2000Q/PhytiumPi) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -78,17 +78,14 @@ bootelf -p 0x90100000 - 系统进入后,输入```intr```查看指令说明 - 输入```intr bin_cre```,启动二进制信号量任务测试 -- 输入```intr bin_del```,删除二进制信号量任务测试 ![bin](./figs/intr_bin.png) - 输入```intr count_cre```,启动计数信号量任务测试 -- 输入```intr count_del```,删除计数信号量任务测试 ![count](./figs/intr_count.png) - 输入```intr queue_cre```,启动在中断服务程序中使用queue测试 -- 输入```intr queue_del```,删除在中断服务程序中使用queue测试 ![queue](./figs/intr_queue.png) diff --git a/example/freertos_feature/interrupt/figs/intr_bin.png b/example/freertos_feature/interrupt/figs/intr_bin.png index 421da8c92b6b154f1e63acdecaa689b527f5fdc1..e18d7de35993dd36c7559b947a05d5fdfde7d92d 100644 Binary files a/example/freertos_feature/interrupt/figs/intr_bin.png and b/example/freertos_feature/interrupt/figs/intr_bin.png differ diff --git a/example/freertos_feature/interrupt/figs/intr_count.png b/example/freertos_feature/interrupt/figs/intr_count.png index 03627251e1974e8dccf399a5e8defc39d9be3ab1..7c27e22b428c2c63ef3d7db7a6f0edf5f9056472 100644 Binary files a/example/freertos_feature/interrupt/figs/intr_count.png and b/example/freertos_feature/interrupt/figs/intr_count.png differ diff --git a/example/freertos_feature/interrupt/figs/intr_queue.png b/example/freertos_feature/interrupt/figs/intr_queue.png index 27f9925fe4caa702ca8313d81f29b9de06af30d3..b5a568ef5e5fe6f426b448a4a11cda5aa3629bfa 100644 Binary files a/example/freertos_feature/interrupt/figs/intr_queue.png and b/example/freertos_feature/interrupt/figs/intr_queue.png differ diff --git a/example/freertos_feature/interrupt/inc/feature_interrupt.h b/example/freertos_feature/interrupt/inc/feature_interrupt.h index a9da368833a82b4a034abdc4be12ff3c4a46c29f..4bdf02a7af10eb6099b049c8a88db55efa3a3e18 100644 --- a/example/freertos_feature/interrupt/inc/feature_interrupt.h +++ b/example/freertos_feature/interrupt/inc/feature_interrupt.h @@ -32,14 +32,9 @@ extern "C" #endif /* interrupt task */ -void CreateBinarySemTasks(void); -void DeleteBinarySemTasks(void); - -void CreateCountSemTasks(void); -void DeleteCountSemTasks(void); - -void CreateQueueTasks(void); -void DeleteQueueTasks(void); +int CreateBinarySemTasks(void); +int CreateCountSemTasks(void); +int CreateQueueTasks(void); #ifdef __cplusplus } diff --git a/example/freertos_feature/interrupt/main.c b/example/freertos_feature/interrupt/main.c index 7b0ddfc5cd1b2a0ddb64a34ffb255e4e6513c90c..0e0ee62fa1364f5be2cb11b80a915d2d46167e1f 100644 --- a/example/freertos_feature/interrupt/main.c +++ b/example/freertos_feature/interrupt/main.c @@ -13,33 +13,66 @@ * * FilePath: main.c * Date: 2023-02-22 08:17:59 - * LastEditTime: 2023-3-1 08:17:59 + * LastEditTime: 2024-5-6 08:17:59 * Description: This file is for nested interrupt test main entry. * * Modify History: * Ver   Who        Date         Changes * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2023/2/23 first release + * 1.1 huangjin 2024/05/06 add no letter shell mode, adapt to auto-test system */ +#include +#include "FreeRTOS.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include +#else +#include "task.h" +#include "feature_interrupt.h" + + +#define FEATURE_INTERRUPT_EXAMPLE_TASK_PRIORITY 2 + +void FeatureInterruptExampleTaskEntry(void *pvParameters) +{ + /* example functions */ + CreateBinarySemTasks(); + CreateCountSemTasks(); + CreateQueueTasks(); + + /* end flag */ + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif int main(void) { - BaseType_t ret; - - ret = LSUserShellTask() ; + BaseType_t ret = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ + +#ifdef CONFIG_USE_LETTER_SHELL + ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)FeatureInterruptExampleTaskEntry, /* 任务入口函数 */ + (const char *)"FeatureInterruptExampleTaskEntry",/* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)FEATURE_INTERRUPT_EXAMPLE_TASK_PRIORITY, /* 任务的优先级 */ + NULL); +#endif if (ret != pdPASS) { goto FAIL_EXIT; } - + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("Failed 0x%x. \r\n", ret); + printf("Feature interrupt example failed in main.c, the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/freertos_feature/interrupt/src/binary_semaphore.c b/example/freertos_feature/interrupt/src/binary_semaphore.c index 51ba48973755a34c117109cc5c6a38c05b50697e..3e96a3ce27cb5b571df4c57fc5c7eff31af7429d 100644 --- a/example/freertos_feature/interrupt/src/binary_semaphore.c +++ b/example/freertos_feature/interrupt/src/binary_semaphore.c @@ -7,11 +7,10 @@ #include "finterrupt.h" #include "fcpu_info.h" - -static xTaskHandle xtask1_handle; -static xTaskHandle xtask2_handle; - #define TASK_STACK_SIZE 1024 +#define PERIODIC_TASK_PRIORITY 3 +#define SEM_TAKE_TASK_PRIORITY 4 +#define BIN_SEM_EXAMPLE_TIMEOUT pdMS_TO_TICKS(10000U) /* The interrupt number to use for the software interrupt generation. This could be any unused number. In this case the first chip level (non system) @@ -26,6 +25,15 @@ numeric values represent low priority values, which can be confusing as it is counter intuitive. */ #define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +enum +{ + BIN_SEM_EXAMPLE_SUCCESS = 0, + BIN_SEM_EXAMPLE_UNKNOWN_STATE, + BIN_SEM_EXAMPLE_FAILURE, +}; + +static QueueHandle_t xQueue = NULL; + /* Macro to force an interrupt. */ static void vTriggerInterrupt(void); @@ -35,12 +43,20 @@ xSemaphoreHandle xBinarySemaphore; void vPeriodicTask(void *pvParameters) { - for (;;) + int task_res = BIN_SEM_EXAMPLE_UNKNOWN_STATE; + + vTaskDelay(500 / portTICK_RATE_MS); + printf("Bin Periodic task - Generate an interrupt.\n"); + vTriggerInterrupt(); + printf("Bin Periodic task - Interrupt generated.\n"); + + if (uxSemaphoreGetCount(xBinarySemaphore) == 0) { - vTaskDelay(5000 / portTICK_RATE_MS); - printf("Bin Periodic task - Generate an interrupt.\n"); - vTriggerInterrupt(); + task_res = BIN_SEM_EXAMPLE_SUCCESS; + xQueueSend(xQueue, &task_res, 0); } + + vTaskDelete(NULL); } void vSemTakeTask(void *pvParameters) @@ -50,7 +66,14 @@ void vSemTakeTask(void *pvParameters) { xSemaphoreTake(xBinarySemaphore, portMAX_DELAY); printf("Bin Handler task - Processing event.\n"); + + if (uxSemaphoreGetCount(xBinarySemaphore) == 0) + { + break; + } } + + vTaskDelete(NULL); } static void vInterruptHandler(s32 vector, void *param) @@ -66,7 +89,6 @@ static void vInterruptHandler(s32 vector, void *param) static void prvSetupSoftwareInterrupt() { GetCpuId(&cpu_id); - vPrintf("cpu_id is %d \r\n", cpu_id); /* The interrupt service routine uses an (interrupt safe) FreeRTOS API function so the interrupt priority must be at or below the priority defined @@ -86,31 +108,48 @@ static void vTriggerInterrupt(void) } -void CreateBinarySemTasks(void) +int CreateBinarySemTasks(void) { + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = BIN_SEM_EXAMPLE_UNKNOWN_STATE; + + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) + { + vPrintString("xQueue create failed."); + goto exit; + } + vSemaphoreCreateBinary(xBinarySemaphore); if (xBinarySemaphore != NULL) { prvSetupSoftwareInterrupt(); - xTaskCreate(vSemTakeTask, "BinHandler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); - xTaskCreate(vPeriodicTask, "BinPeriodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); + xTaskCreate(vSemTakeTask, "BinHandler", TASK_STACK_SIZE, NULL, SEM_TAKE_TASK_PRIORITY, NULL); + xTaskCreate(vPeriodicTask, "BinPeriodic", TASK_STACK_SIZE, NULL, PERIODIC_TASK_PRIORITY, NULL); } -} - -void DeleteBinarySemTasks(void) -{ - if (xtask1_handle) + xReturn = xQueueReceive(xQueue, &task_res, BIN_SEM_EXAMPLE_TIMEOUT); + if (xReturn == pdFAIL) { - vTaskDelete(xtask1_handle); - printf("Bin Handler deletion \r\n"); + vPrintString("xQueue receive timeout."); + goto exit; } - if (xtask2_handle) +exit: + if (xQueue != NULL) { - vTaskDelete(xtask2_handle); - printf("Bin Periodic deletion \r\n"); + vQueueDelete(xQueue); } + if (task_res != BIN_SEM_EXAMPLE_SUCCESS) + { + vPrintString("Binary semaphore feature example [failure]"); + return task_res; + } + else + { + vPrintString("Binary semaphore feature example [success]."); + return task_res; + } } \ No newline at end of file diff --git a/example/freertos_feature/interrupt/src/counting_semaphore.c b/example/freertos_feature/interrupt/src/counting_semaphore.c index 30bf69b16a88fdc29a33eec3c4792d86d4cf9bc0..fc2f13602412855c8b12ea7f69be30cee21497f7 100644 --- a/example/freertos_feature/interrupt/src/counting_semaphore.c +++ b/example/freertos_feature/interrupt/src/counting_semaphore.c @@ -8,10 +8,10 @@ #include "finterrupt.h" #include "fcpu_info.h" -static xTaskHandle xtask1_handle; -static xTaskHandle xtask2_handle; - #define TASK_STACK_SIZE 1024 +#define PERIODIC_TASK_PRIORITY 3 +#define SEM_TAKE_TASK_PRIORITY 4 +#define COUNT_SEM_EXAMPLE_TIMEOUT pdMS_TO_TICKS(10000U) /* The interrupt number to use for the software interrupt generation. This could be any unused number. In this case the first chip level (non system) @@ -26,6 +26,15 @@ numeric values represent low priority values, which can be confusing as it is counter intuitive. */ #define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +enum +{ + COUNT_SEM_EXAMPLE_SUCCESS = 0, + COUNT_SEM_EXAMPLE_UNKNOWN_STATE, + COUNT_SEM_EXAMPLE_FAILURE, +}; + +static QueueHandle_t xQueue = NULL; + /* Macro to force an interrupt. */ static void vTriggerInterrupt(void); @@ -35,24 +44,37 @@ xSemaphoreHandle xCountingSemaphore; static void vPeriodicTask(void *pvParameters) { - for (;;) + int task_res = COUNT_SEM_EXAMPLE_UNKNOWN_STATE; + + vTaskDelay(500 / portTICK_RATE_MS); + printf("Count Periodic task - About to generate an interrupt.\n"); + vTriggerInterrupt(); + printf("Count Periodic task - Interrupt generated.\n"); + + if (uxSemaphoreGetCount(xCountingSemaphore) == 0) { - vTaskDelay(5000 / portTICK_RATE_MS); - printf("Count Periodic task - About to generate an interrupt.\n"); - vTriggerInterrupt(); - printf("Count Periodic task - Interrupt generated.\n\n"); + task_res = COUNT_SEM_EXAMPLE_SUCCESS; + xQueueSend(xQueue, &task_res, 0); } + + vTaskDelete(NULL); } static void vSemTakeTask(void *pvParameters) { xSemaphoreTake(xCountingSemaphore, 0); - for (;;) { xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); printf("Count Handler task - Processing event, sem_count: %d\n", uxSemaphoreGetCount(xCountingSemaphore)); + + if (uxSemaphoreGetCount(xCountingSemaphore) == 0) + { + break; + } } + + vTaskDelete(NULL); } static void vInterruptHandler(s32 vector, void *param) @@ -66,13 +88,11 @@ static void vInterruptHandler(s32 vector, void *param) /* never call taskYIELD() form ISR! */ portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); - } static void prvSetupSoftwareInterrupt(void) { GetCpuId(&cpu_id); - vPrintf("cpu_id is %d \r\n", cpu_id); InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY); @@ -89,31 +109,49 @@ static void vTriggerInterrupt(void) } -void CreateCountSemTasks(void) +int CreateCountSemTasks(void) { + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = COUNT_SEM_EXAMPLE_UNKNOWN_STATE; + + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) + { + vPrintString("xQueue create failed."); + goto exit; + } + xCountingSemaphore = xSemaphoreCreateCounting(10, 0); if (xCountingSemaphore != NULL) { prvSetupSoftwareInterrupt(); - xTaskCreate(vSemTakeTask, "CountHandler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); - xTaskCreate(vPeriodicTask, "CountPeriodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); + xTaskCreate(vSemTakeTask, "CountHandler", TASK_STACK_SIZE, NULL, SEM_TAKE_TASK_PRIORITY, NULL); + xTaskCreate(vPeriodicTask, "CountPeriodic", TASK_STACK_SIZE, NULL, PERIODIC_TASK_PRIORITY, NULL); } -} -void DeleteCountSemTasks(void) -{ - if (xtask1_handle) + xReturn = xQueueReceive(xQueue, &task_res, COUNT_SEM_EXAMPLE_TIMEOUT); + if (xReturn == pdFAIL) { - vTaskDelete(xtask1_handle); - printf("Count Handler deletion \r\n"); + vPrintString("xQueue receive timeout."); + goto exit; } - if (xtask2_handle) +exit: + if (xQueue != NULL) { - vTaskDelete(xtask2_handle); - printf("Count Periodic deletion \r\n"); + vQueueDelete(xQueue); } -} + if (task_res != COUNT_SEM_EXAMPLE_SUCCESS) + { + vPrintString("Count semaphore feature example [failure]"); + return task_res; + } + else + { + vPrintString("Count semaphore feature example [success]."); + return task_res; + } +} \ No newline at end of file diff --git a/example/freertos_feature/interrupt/src/interrupt_cmd.c b/example/freertos_feature/interrupt/src/interrupt_cmd.c index 9e515c65ecee91b979ca24777624cd969451dbdb..650d9a0d3a30e7e505378312adcdecb93e299d06 100644 --- a/example/freertos_feature/interrupt/src/interrupt_cmd.c +++ b/example/freertos_feature/interrupt/src/interrupt_cmd.c @@ -13,48 +13,39 @@ * * FilePath: interrupt_cmd.c * Date: 2022-06-17 10:41:45 - * LastEditTime: 2022-06-17 10:41:45 + * LastEditTime: 2024-05-06 10:41:45 * Description: This file is for interrupt command interface * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2022/08/09 first commit + * 1.1 huangjin 2024/05/06 add no letter shell mode, adapt to auto-test system */ -#include "shell.h" +#include "sdkconfig.h" +#include "FreeRTOS.h" +#include "feature_interrupt.h" #include +#include "task.h" #include -#include "feature_interrupt.h" - -typedef enum -{ - BINARY_SEM_TASK_INDEX = 0, - COUNT_SEM_TASK_INDEX = 1, - QUEUE_TASK_INDEX = 2, - - INTR_FEATURE_LENGTH -} FreeRtosIntrFeatureSelect; +#include "strto.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "../src/shell.h" static void CreateIntrCmdUsage(void) { printf("Usage:\r\n"); - printf(" intr bin_cre \r\n"); - printf(" -- Create intr binary sem tasks now.\r\n"); - printf(" intr bin_del \r\n"); - printf(" -- Del intr binary sem tasks now.\r\n"); - printf(" intr count_cre \r\n"); - printf(" -- Create counting sem tasks now.\r\n"); - printf(" intr count_del \r\n"); - printf(" -- Del counting sem tasks now.\r\n"); - printf(" intr queue_cre \r\n"); - printf(" -- Create queue tasks now.\r\n"); - printf(" intr queue_del \r\n"); - printf(" -- Del queue tasks now.\r\n"); + printf("intr bin_cre \r\n"); + printf("-- Create intr binary sem tasks now.\r\n"); + printf("intr count_cre \r\n"); + printf("-- Create counting sem tasks now.\r\n"); + printf("intr queue_cre \r\n"); + printf("-- Create queue tasks now.\r\n"); } int CreateIntrCmd(int argc, char *argv[]) { - static int create_flg[INTR_FEATURE_LENGTH] = {0}; /* 1 is tasks has been created*/ + int ret = 0; if (argc < 2) { @@ -64,84 +55,23 @@ int CreateIntrCmd(int argc, char *argv[]) if (!strcmp(argv[1], "bin_cre")) { - if (create_flg[BINARY_SEM_TASK_INDEX] == 0) - { - CreateBinarySemTasks(); - create_flg[BINARY_SEM_TASK_INDEX] = 1; - } - else - { - printf("Please use bin_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "bin_del")) - { - if (create_flg[BINARY_SEM_TASK_INDEX] == 1) - { - DeleteBinarySemTasks(); - create_flg[BINARY_SEM_TASK_INDEX] = 0; - } - else - { - printf("Please use bin_cre cmd first. \r\n"); - } + ret = CreateBinarySemTasks(); } else if (!strcmp(argv[1], "count_cre")) { - if (create_flg[COUNT_SEM_TASK_INDEX] == 0) - { - CreateCountSemTasks(); - create_flg[COUNT_SEM_TASK_INDEX] = 1; - } - else - { - printf("Please use count_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "count_del")) - { - if (create_flg[COUNT_SEM_TASK_INDEX] == 1) - { - DeleteCountSemTasks(); - create_flg[COUNT_SEM_TASK_INDEX] = 0; - } - else - { - printf("Please use count_cre cmd first. \r\n"); - } + ret = CreateCountSemTasks(); } else if (!strcmp(argv[1], "queue_cre")) { - if (create_flg[QUEUE_TASK_INDEX] == 0) - { - CreateQueueTasks(); - create_flg[QUEUE_TASK_INDEX] = 1; - } - else - { - printf("Please use queue_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "queue_del")) - { - if (create_flg[QUEUE_TASK_INDEX] == 1) - { - DeleteQueueTasks(); - create_flg[QUEUE_TASK_INDEX] = 0; - } - else - { - printf("Please use queue_cre cmd first. \r\n"); - } + ret = CreateQueueTasks(); } else { printf("Error: Invalid arguments. \r\n"); CreateIntrCmdUsage(); } - return 0; + return ret; } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), intr, CreateIntrCmd, intr task test); - - +#endif \ No newline at end of file diff --git a/example/freertos_feature/interrupt/src/queue_from_interrupt.c b/example/freertos_feature/interrupt/src/queue_from_interrupt.c index 079f48f12c4aa34ff057074fb4aabae0def67dd8..0b67e2f30fedd038103fa816ec5004a51df14c65 100644 --- a/example/freertos_feature/interrupt/src/queue_from_interrupt.c +++ b/example/freertos_feature/interrupt/src/queue_from_interrupt.c @@ -8,10 +8,11 @@ #include "finterrupt.h" #include "fcpu_info.h" -static xTaskHandle xtask1_handle; -static xTaskHandle xtask2_handle; - -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 +#define INTEGER_GENERATOR_TASK_PRIORITY 3 +#define STRING_PRINTER_TAKE_TASK_PRIORITY 4 +#define QUEUE_INTR_RECV_TIMES 5 +#define QUEUE_INTR_EXAMPLE_TIMEOUT pdMS_TO_TICKS(10000U) /* The interrupt number to use for the software interrupt generation. This could be any unused number. In this case the first chip level (non system) @@ -26,6 +27,15 @@ numeric values represent low priority values, which can be confusing as it is counter intuitive. */ #define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +enum +{ + QUEUE_INTR_EXAMPLE_SUCCESS = 0, + QUEUE_INTR_EXAMPLE_UNKNOWN_STATE, + QUEUE_INTR_EXAMPLE_FAILURE, +}; + +static QueueHandle_t xQueue = NULL; + /* Macro to force an interrupt. */ static void vTriggerInterrupt(void); @@ -36,17 +46,17 @@ static xQueueHandle xStringQueue; static void vIntegerGenerator(void *pvParameters) { + int task_res = QUEUE_INTR_EXAMPLE_UNKNOWN_STATE; portTickType xLastExecutionTime; unsigned long ulValueToSend = 0; - int i; xLastExecutionTime = xTaskGetTickCount(); for (;;) { - vTaskDelayUntil(&xLastExecutionTime, 5000 / portTICK_RATE_MS); + vTaskDelayUntil(&xLastExecutionTime, 500 / portTICK_RATE_MS); - for (i = 0; i < 5; ++i) + for (int i = 0; i < QUEUE_INTR_RECV_TIMES; ++i) { xQueueSendToBack(xIntegerQueue, &ulValueToSend, 0); ++ulValueToSend; @@ -54,8 +64,17 @@ static void vIntegerGenerator(void *pvParameters) vPrintf("Queue Periodic task - About to generate an interrupt.\n"); vTriggerInterrupt(); - vPrintf("Queue Periodic task - Interrupt generated.\n\n"); + vPrintf("Queue Periodic task - Interrupt generated.\n"); + + if ( uxQueueMessagesWaiting(xIntegerQueue) == 0 && uxQueueMessagesWaiting(xStringQueue) == 0) + { + task_res = QUEUE_INTR_EXAMPLE_SUCCESS; + xQueueSend(xQueue, &task_res, 0); + break; + } } + + vTaskDelete(NULL); } static void vInterruptHandler(s32 vector, void *param) @@ -75,31 +94,39 @@ static void vInterruptHandler(s32 vector, void *param) &xHigherPriorityTaskWoken) != errQUEUE_EMPTY) { - // last 2 bits: values 0-3 + /* last 2 bits: values 0-3 */ ulReceivedNumber &= 0x03; xQueueSendToBackFromISR(xStringQueue, &pcStrings[ulReceivedNumber], &xHigherPriorityTaskWoken); } - // never call taskYIELD() form ISR! + /* never call taskYIELD() form ISR! */ portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } static void vStringPrinter(void *pvParameters) { char *pcString; + int queue_intr_recv_times = 0; for (;;) { xQueueReceive(xStringQueue, &pcString, portMAX_DELAY); vPrintf("pcString = %s\n", pcString); + queue_intr_recv_times++; + + if (queue_intr_recv_times == QUEUE_INTR_RECV_TIMES) + { + break; + } } + + vTaskDelete(NULL); } static void prvSetupSoftwareInterrupt(void) { GetCpuId(&cpu_id); - vPrintf("cpu_id is %d \r\n", cpu_id); InterruptSetPriority(INTERRUPT_ID, INTERRUPT_PRIORITY); @@ -115,29 +142,47 @@ static void vTriggerInterrupt(void) InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); } -void CreateQueueTasks(void) +int CreateQueueTasks(void) { + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = QUEUE_INTR_EXAMPLE_UNKNOWN_STATE; + + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) + { + vPrintString("xQueue create failed."); + goto exit; + } + xIntegerQueue = xQueueCreate(10, sizeof(unsigned long)); xStringQueue = xQueueCreate(10, sizeof(char *)); prvSetupSoftwareInterrupt(); - xTaskCreate(vIntegerGenerator, "QueueIntGen", TASK_STACK_SIZE, NULL, 1, &xtask1_handle); - xTaskCreate(vStringPrinter, "QueueString", TASK_STACK_SIZE, NULL, 2, &xtask2_handle); + xTaskCreate(vIntegerGenerator, "QueueIntGen", TASK_STACK_SIZE, NULL, INTEGER_GENERATOR_TASK_PRIORITY, NULL); + xTaskCreate(vStringPrinter, "QueueString", TASK_STACK_SIZE, NULL, STRING_PRINTER_TAKE_TASK_PRIORITY, NULL); -} + xReturn = xQueueReceive(xQueue, &task_res, QUEUE_INTR_EXAMPLE_TIMEOUT); + if (xReturn == pdFAIL) + { + vPrintString("xQueue receive timeout."); + goto exit; + } -void DeleteQueueTasks(void) -{ - if (xtask1_handle) +exit: + if (xQueue != NULL) { - vTaskDelete(xtask1_handle); - printf("Queue IntGen deletion \r\n"); + vQueueDelete(xQueue); } - if (xtask2_handle) + if (task_res != QUEUE_INTR_EXAMPLE_SUCCESS) + { + vPrintString("Queue from interrupt feature example [failure]"); + return task_res; + } + else { - vTaskDelete(xtask2_handle); - printf("Queue String deletion \r\n"); + vPrintString("Queue from interrupt feature example [success]."); + return task_res; } } \ No newline at end of file diff --git a/example/freertos_feature/queue/README.md b/example/freertos_feature/queue/README.md index 43f4457fd505e2a69a330a2fe594492209f0db80..3c7194c23d2f855b2f4cde7112be140a0c9de6cd 100644 --- a/example/freertos_feature/queue/README.md +++ b/example/freertos_feature/queue/README.md @@ -5,11 +5,16 @@ 本例程示范了freertos环境下的queue的使用。 队列又称消息队列,是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任务间传递信息,实现了任务接收来自其他任务或中断的不固定长度的消息,任务能够从队列里面读取消息,当队列中的消息是空时,读取消息的任务将被阻塞,用户还可以指定阻塞的任务时间 xTicksToWait,在这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效。当队列中有新消息时,被阻塞的任务会被唤醒并处理新消息;当等待的时间超过了指定的阻塞时间,即使队列中尚无有效数据,任务也会自动从阻塞态转为就绪态。消息队列是一种异步的通信方式。 +本例程展示了队列的三种使用方法: +1. 使用队列传输int类型数据(queue_int_send_recv.c) +2. 使用队列传输结构体数据(queue_struct_send_recv.c) +3. 队列集的使用(queue_set.c) + ## 2. 如何使用例程 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -77,20 +82,20 @@ bootelf -p 0x90100000 ### 2.4 输出与实验现象 - 系统进入后,输入```queue```查看指令说明 + +![queue_cmd](./figs/queue_cmd.png) + - 输入```queue int_cre```,启动queue的int类型数据的收发任务测试 -- 输入```queue int_del```,删除queue的int类型数据的收发任务测试 -![int](./figs/queue_int.png) +![int_cre](./figs/int_cre.png) - 输入```queue struct_cre```,启动queue的struct类型数据的收发任务测试 -- 输入```queue struct_del```,删除queue的struct类型数据的收发任务测试 -![struct](./figs/queue_struct.png) +![struct_cre](./figs/struct_cre.png) - 输入```queue set_cre```,启动queue的set函数使用,收发任务测试 -- 输入```queue set_del```,删除queue的set函数使用,收发任务测试 -![set](./figs/queue_set.png) +![set_cre](./figs/set_cre.png) - 测试任务能够能正常创建和删除,输入```ps```查看任务状态正常,即测试正常 diff --git a/example/freertos_feature/queue/figs/int_cre.png b/example/freertos_feature/queue/figs/int_cre.png new file mode 100644 index 0000000000000000000000000000000000000000..a95c4687a8738e52724e23b34d5d5ae9cc72c368 Binary files /dev/null and b/example/freertos_feature/queue/figs/int_cre.png differ diff --git a/example/freertos_feature/queue/figs/queue_cmd.png b/example/freertos_feature/queue/figs/queue_cmd.png new file mode 100644 index 0000000000000000000000000000000000000000..91c1033d569eb10b742e3f1f7f86e32e67acbc85 Binary files /dev/null and b/example/freertos_feature/queue/figs/queue_cmd.png differ diff --git a/example/freertos_feature/queue/figs/queue_int.png b/example/freertos_feature/queue/figs/queue_int.png deleted file mode 100644 index e93b660ff73209df088d566cf1ec87b362bf9868..0000000000000000000000000000000000000000 Binary files a/example/freertos_feature/queue/figs/queue_int.png and /dev/null differ diff --git a/example/freertos_feature/queue/figs/queue_set.png b/example/freertos_feature/queue/figs/queue_set.png deleted file mode 100644 index 154203ede093dd1e7f312a8a357ceab48d9f4156..0000000000000000000000000000000000000000 Binary files a/example/freertos_feature/queue/figs/queue_set.png and /dev/null differ diff --git a/example/freertos_feature/queue/figs/queue_struct.png b/example/freertos_feature/queue/figs/queue_struct.png deleted file mode 100644 index c8cf5b182a0c493e66f6886c3eae33f51afa5783..0000000000000000000000000000000000000000 Binary files a/example/freertos_feature/queue/figs/queue_struct.png and /dev/null differ diff --git a/example/freertos_feature/queue/figs/set_cre.png b/example/freertos_feature/queue/figs/set_cre.png new file mode 100644 index 0000000000000000000000000000000000000000..31ac0b6eabedfeaf43861de2c4bdae4860b32daf Binary files /dev/null and b/example/freertos_feature/queue/figs/set_cre.png differ diff --git a/example/freertos_feature/queue/figs/struct_cre.png b/example/freertos_feature/queue/figs/struct_cre.png new file mode 100644 index 0000000000000000000000000000000000000000..dd3a8800634836b969a76943d8a0b49140ee6dae Binary files /dev/null and b/example/freertos_feature/queue/figs/struct_cre.png differ diff --git a/example/freertos_feature/queue/inc/feature_queue.h b/example/freertos_feature/queue/inc/feature_queue.h index 7eb5872ccf487abf08f3d54d3ad7e380cd4c670d..d029acaa35915086a9a22518468402414645d4cd 100644 --- a/example/freertos_feature/queue/inc/feature_queue.h +++ b/example/freertos_feature/queue/inc/feature_queue.h @@ -26,20 +26,17 @@ #ifndef FEATURE_QUEUE_H #define FEATURE_QUEUE_H +#include "FreeRTOS.h" + #ifdef __cplusplus extern "C" { #endif /* queue task */ -void CreateIntTasks(void); -void DeleteIntTasks(void); - -void CreateStructTasks(void); -void DeleteStructTasks(void); - -void CreateQueueSetTasks(void); -void DeleteQueueSetTasks(void); +BaseType_t CreateIntTasks(void); +BaseType_t CreateStructTasks(void); +BaseType_t CreateQueueSetTasks(void); #ifdef __cplusplus } diff --git a/example/freertos_feature/queue/main.c b/example/freertos_feature/queue/main.c index 7e219b2eae3ee415a34d3c9fb22d95b286820e60..a74c1c78c0951c5fd5c5b96bfc0f4d8afef53708 100644 --- a/example/freertos_feature/queue/main.c +++ b/example/freertos_feature/queue/main.c @@ -22,19 +22,48 @@ * 1.0 wangxiaodong 2022/06/20 first commit */ +#include +#include "FreeRTOS.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include +#else +#include "task.h" +#include "feature_queue.h" +void QueueExampleTaskEntry(void) +{ + CreateIntTasks(); + CreateStructTasks(); + CreateQueueSetTasks(); + + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif int main(void) { BaseType_t ret; +#ifdef CONFIG_USE_LETTER_SHELL ret = LSUserShellTask() ; if (ret != pdPASS) { goto FAIL_EXIT; } +#else + + taskENTER_CRITICAL(); /*进入临界区*/ + ret = xTaskCreate((TaskFunction_t)QueueExampleTaskEntry, /* 任务入口函数 */ + (const char *)"QueueExampleTaskEntry",/* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)8, /* 任务的优先级 */ + NULL); + taskEXIT_CRITICAL(); /*退出临界区*/ + +#endif vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ diff --git a/example/freertos_feature/queue/sdkconfig b/example/freertos_feature/queue/sdkconfig index 19a410647363c0f5384cd33c063022c86a5c0595..582fe74201673ce9d2aab9a1037824da8a8bd78a 100644 --- a/example/freertos_feature/queue/sdkconfig +++ b/example/freertos_feature/queue/sdkconfig @@ -53,7 +53,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set diff --git a/example/freertos_feature/queue/sdkconfig.h b/example/freertos_feature/queue/sdkconfig.h index 9ed2dbe5abd8422145707ff8ca679c21e684c7f4..5174dd79a0a79d3f9356d77a56078c3d36304627 100644 --- a/example/freertos_feature/queue/sdkconfig.h +++ b/example/freertos_feature/queue/sdkconfig.h @@ -51,7 +51,6 @@ #define CONFIG_F64BIT_MEMORY_ADDRESS 0x2000000000 #define CONFIG_F64BIT_MEMORY_LENGTH 0x800000000 #define CONFIG_TARGET_E2000 -/* CONFIG_USE_SPINLOCK is not set */ #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 /* CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set */ /* CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set */ diff --git a/example/freertos_feature/queue/src/queue_cmd.c b/example/freertos_feature/queue/src/queue_cmd.c index e94725325f6565d6241affbd91ec805d49efb3ff..2bfacc025ec9d20cc841a6c2d65b471a2817614d 100644 --- a/example/freertos_feature/queue/src/queue_cmd.c +++ b/example/freertos_feature/queue/src/queue_cmd.c @@ -21,40 +21,26 @@ * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2022/08/09 first commit */ -#include "shell.h" #include #include #include "feature_queue.h" - -typedef enum -{ - INT_TASK_INDEX = 0, - STRUCT_TASK_INDEX = 1, - SET_TASK_INDEX = 2, - QUEUE_FEATURE_LENGTH -} FreeRtosQueueFeatureSelect; +#include "sdkconfig.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "../src/shell.h" static void CreateQueueCmdUsage(void) { printf("Usage:\r\n"); printf(" queue int_cre \r\n"); printf(" -- Create int queue send and receive tasks now.\r\n"); - printf(" queue int_del \r\n"); - printf(" -- Del int queue send and receive tasks now.\r\n"); printf(" queue struct_cre \r\n"); printf(" -- Create struct queue send and receive tasks now.\r\n"); - printf(" queue struct_del \r\n"); - printf(" -- Cel struct queue send and receive tasks now.\r\n"); printf(" queue set_cre \r\n"); printf(" -- Use queue set function, create send and receive tasks now.\r\n"); - printf(" queue set_del \r\n"); - printf(" -- Del queue set, send and receive tasks now.\r\n"); } int CreateQueueCmd(int argc, char *argv[]) { - static int create_flg[QUEUE_FEATURE_LENGTH] = {0}; /* 1 is tasks has been created*/ - if (argc < 2) { CreateQueueCmdUsage(); @@ -63,75 +49,15 @@ int CreateQueueCmd(int argc, char *argv[]) if (!strcmp(argv[1], "int_cre")) { - if (create_flg[INT_TASK_INDEX] == 0) - { - CreateIntTasks(); - create_flg[INT_TASK_INDEX] = 1; - } - else - { - printf("Please use int_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "int_del")) - { - if (create_flg[INT_TASK_INDEX] == 1) - { - DeleteIntTasks(); - create_flg[INT_TASK_INDEX] = 0; - } - else - { - printf("Please use int_cre cmd first. \r\n"); - } + CreateIntTasks(); } else if (!strcmp(argv[1], "struct_cre")) { - if (create_flg[STRUCT_TASK_INDEX] == 0) - { - CreateStructTasks(); - create_flg[STRUCT_TASK_INDEX] = 1; - } - else - { - printf("Please use struct_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "struct_del")) - { - if (create_flg[STRUCT_TASK_INDEX] == 1) - { - DeleteStructTasks(); - create_flg[STRUCT_TASK_INDEX] = 0; - } - else - { - printf("Please use struct_cre cmd first. \r\n"); - } + CreateStructTasks(); } else if (!strcmp(argv[1], "set_cre")) { - if (create_flg[SET_TASK_INDEX] == 0) - { - CreateQueueSetTasks(); - create_flg[SET_TASK_INDEX] = 1; - } - else - { - printf("Please use set_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "set_del")) - { - if (create_flg[SET_TASK_INDEX] == 1) - { - DeleteQueueSetTasks(); - create_flg[SET_TASK_INDEX] = 0; - } - else - { - printf("Please use set_cre cmd first. \r\n"); - } + CreateQueueSetTasks(); } else { @@ -142,5 +68,6 @@ int CreateQueueCmd(int argc, char *argv[]) } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), queue, CreateQueueCmd, queue task creating test); +#endif diff --git a/example/freertos_feature/queue/src/queue_int_send_recv.c b/example/freertos_feature/queue/src/queue_int_send_recv.c index a51206b7a34fa63a3ff7e2621dc345477bcc4800..f7e3f7fcec885562809faf111ee070e83b677254 100644 --- a/example/freertos_feature/queue/src/queue_int_send_recv.c +++ b/example/freertos_feature/queue/src/queue_int_send_recv.c @@ -8,8 +8,10 @@ that receives from the queue does. #include "FreeRTOS.h" #include "task.h" #include "queue.h" +#include "event_groups.h" #define TASK_STACK_SIZE 2048 +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; @@ -26,53 +28,10 @@ static void vReceiverTask(void *pvParameters); that is accessed by all three tasks. */ static QueueHandle_t xQueue; -void CreateIntTasks(void) -{ - /* The queue is created to hold a maximum of 5 int values. */ - xQueue = xQueueCreate(5, sizeof(int)); - - if (xQueue != NULL) - { - /* Create two instances of the task that will write to the queue. The - parameter is used to pass the value that the task should write to the queue, - so one task will continuously write 100 to the queue while the other task - will continuously write 200 to the queue. Both tasks are created at - priority 1. */ - xTaskCreate(vSenderTask, "Queue Sender1", TASK_STACK_SIZE, (void *) 100, 2, &xtask1_handle); - xTaskCreate(vSenderTask, "Queue Sender2", TASK_STACK_SIZE, (void *) 200, 2, &xtask2_handle); - - /* Create the task that will read from the queue. The task is created with - priority 2, so above the priority of the sender tasks. */ - xTaskCreate(vReceiverTask, "Queue Receiver", TASK_STACK_SIZE, NULL, 3, &xtask3_handle); +static EventGroupHandle_t xEventGroup; +#define FIRST_SENDER_TASK_BIT ( 1UL << 0UL ) /* Event bit 0, which is set by a task. */ +#define SECOND_SENDER_TASK_BIT ( 1UL << 1UL ) /* Event bit 1, which is set by a task. */ - } - else - { - /* The queue could not be created. */ - } - -} - -void DeleteIntTasks(void) -{ - if (xtask1_handle) - { - vTaskDelete(xtask1_handle); - vPrintString("Int Sender 1 deletion \r\n"); - } - - if (xtask2_handle) - { - vTaskDelete(xtask2_handle); - vPrintString("Int Sender 2 deletion \r\n"); - } - - if (xtask3_handle) - { - vTaskDelete(xtask3_handle); - vPrintString("Int Receiver deletion \r\n"); - } -} /*-----------------------------------------------------------*/ static void vSenderTask(void *pvParameters) @@ -108,7 +67,7 @@ static void vSenderTask(void *pvParameters) vPrintString("Could not send to the queue.\r\n"); } - vTaskDelay(3000); + vTaskDelay(500); } } /*-----------------------------------------------------------*/ @@ -118,7 +77,6 @@ static void vReceiverTask(void *pvParameters) /* Declare the variable that will hold the values received from the queue. */ int32_t lReceivedValue; BaseType_t xStatus; - const TickType_t xTicksToWait = pdMS_TO_TICKS(5000UL); /* This task is also defined within an infinite loop. */ for (;;) @@ -141,21 +99,90 @@ static void vReceiverTask(void *pvParameters) the last parameter is the block time – the maximum amount of time that the task should remain in the Blocked state to wait for data to be available should the queue already be empty. */ - xStatus = xQueueReceive(xQueue, &lReceivedValue, xTicksToWait); + xStatus = xQueueReceive(xQueue, &lReceivedValue, portMAX_DELAY); if (xStatus == pdPASS) { - /* Data was successfully received from the queue, print out the received - value. */ - vPrintStringAndNumber("Received = ", lReceivedValue); + if (lReceivedValue == 100) + { + vTaskDelete(xtask1_handle); + vPrintStringAndNumber("Received From Sender 1 = ", lReceivedValue); + xEventGroupSetBits(xEventGroup, FIRST_SENDER_TASK_BIT); + } + else if (lReceivedValue == 200) + { + vTaskDelete(xtask2_handle); + vPrintStringAndNumber("Received From Sender 2 = ", lReceivedValue); + xEventGroupSetBits(xEventGroup, SECOND_SENDER_TASK_BIT); + } } - else + } +} + +void DeleteIntTasks(void) +{ + if (xtask3_handle) + { + vTaskDelete(xtask3_handle); + vPrintString("Int Receiver deletion."); + } +} + +BaseType_t CreateIntTasks(void) +{ + BaseType_t ret; + EventBits_t xEventGroupValue; + const EventBits_t xBitsToWaitFor = (FIRST_SENDER_TASK_BIT | SECOND_SENDER_TASK_BIT); + + xEventGroup = xEventGroupCreate(); + /* The queue is created to hold a maximum of 5 int values. */ + xQueue = xQueueCreate(5, sizeof(int)); + + if (xQueue != NULL) + { + /* Create two instances of the task that will write to the queue. The + parameter is used to pass the value that the task should write to the queue, + so one task will continuously write 100 to the queue while the other task + will continuously write 200 to the queue. Both tasks are created at + priority 1. */ + ret = xTaskCreate(vSenderTask, "Queue Sender1", TASK_STACK_SIZE, (void *) 100, 2, &xtask1_handle); + if (ret != pdPASS) { - /* We did not receive anything from the queue even after waiting for 100ms. - This must be an error as the sending tasks are free running and will be - continuously writing to the queue. */ - vPrintString("Could not receive from the queue.\r\n"); + xtask1_handle = NULL; + vPrintStringAndNumber("Sender 1 creation failed: ", ret); + goto exit; } + ret = xTaskCreate(vSenderTask, "Queue Sender2", TASK_STACK_SIZE, (void *) 200, 2, &xtask2_handle); + if (ret != pdPASS) + { + xtask2_handle = NULL; + vPrintStringAndNumber("Sender 2 creation failed: ", ret); + goto exit; + } + /* Create the task that will read from the queue. The task is created with + priority 2, so above the priority of the sender tasks. */ + ret = xTaskCreate(vReceiverTask, "Queue Receiver", TASK_STACK_SIZE, NULL, 3, &xtask3_handle); + if (ret != pdPASS) + { + xtask3_handle = NULL; + vPrintStringAndNumber("Receiver creation failed: ", ret); + goto exit; + } + + } + /* Block to wait for event bits to become set within the event group. */ + xEventGroupValue = xEventGroupWaitBits(xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, TIMER_OUT); +exit: + DeleteIntTasks(); + if (xEventGroupValue != xBitsToWaitFor) + { + vPrintf("%s@%d: Queue int send then recv example [failure].\r\n", __func__, __LINE__); + return pdFAIL; + } + else + { + vPrintf("%s@%d: Queue int send then recv example [success].\r\n", __func__, __LINE__); + return pdTRUE; } } \ No newline at end of file diff --git a/example/freertos_feature/queue/src/queue_set.c b/example/freertos_feature/queue/src/queue_set.c index 1ef8af7943566d458659af88aa802d4b0ddec7e7..30322ace1210ee9ace47ac5cb73af53ea6333b79 100644 --- a/example/freertos_feature/queue/src/queue_set.c +++ b/example/freertos_feature/queue/src/queue_set.c @@ -7,13 +7,18 @@ the two queues contain data. #include "FreeRTOS.h" #include "task.h" #include "queue.h" +#include "event_groups.h" #define TASK_STACK_SIZE 2048 +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) static xTaskHandle xtask1_handle; static xTaskHandle xtask2_handle; static xTaskHandle xtask3_handle; +static EventGroupHandle_t xEventGroup; +#define FIRST_SENDER_TASK_BIT ( 1UL << 0UL ) /* Event bit 0, which is set by a task. */ +#define SECOND_SENDER_TASK_BIT ( 1UL << 1UL ) /* Event bit 1, which is set by a task. */ /* The three sender task. */ static void vSenderTask1(void *pvParameters); @@ -28,68 +33,29 @@ static void vReceiverTask(void *pvParameters); /* Declare two variables of type QueueHandle_t. Both queues are added to the same queue set. */ static QueueHandle_t xQueue1 = NULL, xQueue2 = NULL; +static int xQueue1_recv_success_flag = 0; +static int xQueue2_recv_success_flag = 0; +enum +{ + XQUEUE1_MESSAGE = 1, + XQUEUE2_MESSAGE = 2, +}; /* Declare a variable of type QueueSetHandle_t. This is the queue set to which the two queues are added. */ static QueueSetHandle_t xQueueSet = NULL; -void CreateQueueSetTasks(void) -{ - /* Create the two queues. Each queue sends character pointers. The - priority of the receiving task is above the priority of the sending tasks so - the queues will never have more than one item in them at any one time. */ - xQueue1 = xQueueCreate(1, sizeof(char *)); - xQueue2 = xQueueCreate(1, sizeof(char *)); - - /* Create the queue set. There are two queues both of which can contain - 1 item, so the maximum number of queue handle the queue set will ever have - to hold is 2 (1 item multiplied by 2 sets). */ - xQueueSet = xQueueCreateSet(1 * 2); - - /* Add the two queues to the set. */ - xQueueAddToSet(xQueue1, xQueueSet); - xQueueAddToSet(xQueue2, xQueueSet); - - /* Create the tasks that send to the queues. */ - xTaskCreate(vSenderTask1, "QueueSet Sender1", TASK_STACK_SIZE, NULL, 2, &xtask1_handle); - xTaskCreate(vSenderTask2, "QueueSet Sender2", TASK_STACK_SIZE, NULL, 2, &xtask2_handle); - - /* Create the receiver task. */ - xTaskCreate(vReceiverTask, "QueueSet Receiver", TASK_STACK_SIZE, NULL, 3, &xtask3_handle); - -} - -void DeleteQueueSetTasks(void) -{ - if (xtask1_handle) - { - vTaskDelete(xtask1_handle); - vPrintString("QueueSet Sender 1 deletion \r\n"); - } - - if (xtask2_handle) - { - vTaskDelete(xtask2_handle); - vPrintString("QueueSet Sender 2 deletion \r\n"); - } - - if (xtask3_handle) - { - vTaskDelete(xtask3_handle); - vPrintString("QueueSet Receiver deletion \r\n"); - } -} /*-----------------------------------------------------------*/ static void vSenderTask1(void *pvParameters) { - const TickType_t xBlockTime = pdMS_TO_TICKS(5000); - const char *const pcMessage = "Message from vSenderTask1\r\n"; + const TickType_t xBlockTime = pdMS_TO_TICKS(500); + const int pcMessage = XQUEUE1_MESSAGE; /* As per most tasks, this task is implemented within an infinite loop. */ for (;;) { - /* Block for 100ms. */ + /* Block for 200ms. */ vTaskDelay(xBlockTime); /* Send this task's string to xQueue1. It is not necessary to use a @@ -106,8 +72,8 @@ static void vSenderTask1(void *pvParameters) static void vSenderTask2(void *pvParameters) { - const TickType_t xBlockTime = pdMS_TO_TICKS(5000); - const char *const pcMessage = "Message from vSenderTask2\r\n"; + const TickType_t xBlockTime = pdMS_TO_TICKS(500); + const int pcMessage = XQUEUE2_MESSAGE; /* As per most tasks, this task is implemented within an infinite loop. */ for (;;) @@ -130,7 +96,7 @@ static void vSenderTask2(void *pvParameters) static void vReceiverTask(void *pvParameters) { QueueHandle_t xQueueThatContainsData; - char *pcReceivedString; + int pcReceivedMessage; /* As per most tasks, this task is implemented within an infinite loop. */ for (;;) @@ -147,11 +113,103 @@ static void vReceiverTask(void *pvParameters) the set contained data, and xQueueThatContansData must be valid. Read from the queue. It is not necessary to specify a block time because it is known that the queue contains data. The block time is set to 0. */ - xQueueReceive(xQueueThatContainsData, &pcReceivedString, 0); - - /* Print the string received from the queue. */ - vPrintString(pcReceivedString); + xQueueReceive(xQueueThatContainsData, &pcReceivedMessage, 0); + + if (pcReceivedMessage == XQUEUE1_MESSAGE) + { + vTaskDelete(xtask1_handle); + vPrintStringAndNumber("Received From xQueue1 = ", pcReceivedMessage); + xEventGroupSetBits(xEventGroup, FIRST_SENDER_TASK_BIT); + } + else if (pcReceivedMessage == XQUEUE2_MESSAGE) + { + vTaskDelete(xtask2_handle); + vPrintStringAndNumber("Received From xQueue2 = ", pcReceivedMessage); + xEventGroupSetBits(xEventGroup, SECOND_SENDER_TASK_BIT); + } + } +} +void DeleteQueueSetTasks(void) +{ + if (xtask3_handle) + { + vTaskDelete(xtask3_handle); + vPrintString("QueueSet Receiver deletion."); } } +BaseType_t CreateQueueSetTasks(void) +{ + BaseType_t ret; + EventBits_t xEventGroupValue; + const EventBits_t xBitsToWaitFor = (FIRST_SENDER_TASK_BIT | SECOND_SENDER_TASK_BIT); + /* Create the two queues. Each queue sends character pointers. The + priority of the receiving task is above the priority of the sending tasks so + the queues will never have more than one item in them at any one time. */ + xQueue1 = xQueueCreate(1, sizeof(int *)); + xQueue2 = xQueueCreate(1, sizeof(int *)); + + xEventGroup = xEventGroupCreate(); + /* Create the queue set. There are two queues both of which can contain + 1 item, so the maximum number of queue handle the queue set will ever have + to hold is 2 (1 item multiplied by 2 sets). */ + xQueueSet = xQueueCreateSet(1 * 2); + + /* Add the two queues to the set. */ + ret = xQueueAddToSet(xQueue1, xQueueSet); + if (ret != pdPASS) + { + vPrintStringAndNumber("xQueue1 add xQueueSet failed", ret); + goto exit; + } + + ret = xQueueAddToSet(xQueue2, xQueueSet); + if (ret != pdPASS) + { + vPrintStringAndNumber("xQueue2 add xQueueSet failed", ret); + goto exit; + } + /* Create the tasks that send to the queues. */ + ret = xTaskCreate(vSenderTask1, "QueueSet Sender1", TASK_STACK_SIZE, NULL, 2, &xtask1_handle); + if (ret != pdPASS) + { + xtask1_handle = NULL; + vPrintStringAndNumber("Sender 1 creation failed: ", ret); + goto exit; + } + + ret = xTaskCreate(vSenderTask2, "QueueSet Sender2", TASK_STACK_SIZE, NULL, 2, &xtask2_handle); + if (ret != pdPASS) + { + xtask2_handle = NULL; + vPrintStringAndNumber("Sender 2 creation failed: ", ret); + goto exit; + } + + /* Create the receiver task. */ + ret = xTaskCreate(vReceiverTask, "QueueSet Receiver", TASK_STACK_SIZE, NULL, 3, &xtask3_handle); + if (ret != pdPASS) + { + xtask3_handle = NULL; + vPrintStringAndNumber("Receiver creation failed: ", ret); + goto exit; + } + /* Block to wait for event bits to become set within the event group. */ + xEventGroupValue = xEventGroupWaitBits(xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, TIMER_OUT); + +exit: + DeleteQueueSetTasks(); + + if (xEventGroupValue != xBitsToWaitFor) + { + vPrintf("%s@%d: Queue set example [failure].\r\n", __func__, __LINE__); + return pdFAIL; + } + else + { + vPrintf("%s@%d: Queue set example [success].\r\n", __func__, __LINE__); + return pdTRUE; + } + +} \ No newline at end of file diff --git a/example/freertos_feature/queue/src/queue_struct_send_recv.c b/example/freertos_feature/queue/src/queue_struct_send_recv.c index 77a9c30a23eaf29318c61c7b1600b472b337ef69..db7b1acd28ddd7c0f7ed2723af60c7f7ad555744 100644 --- a/example/freertos_feature/queue/src/queue_struct_send_recv.c +++ b/example/freertos_feature/queue/src/queue_struct_send_recv.c @@ -6,8 +6,10 @@ has a lower priority than the sending tasks. Also, the queue is used to pass str #include "FreeRTOS.h" #include "task.h" #include "queue.h" +#include "event_groups.h" #define TASK_STACK_SIZE 2048 +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) #define mainSENDER_1 0 #define mainSENDER_2 1 @@ -28,6 +30,10 @@ static const xData xStructsToSend[2] = {2, mainSENDER_2} /* Used by Sender2. */ }; +static EventGroupHandle_t xEventGroup; +#define FIRST_SENDER_TASK_BIT ( 1UL << 0UL ) /* Event bit 0, which is set by a task. */ +#define SECOND_SENDER_TASK_BIT ( 1UL << 1UL ) /* Event bit 1, which is set by a task. */ + /* Declare a variable of type QueueHandle_t. This is used to store the queue that is accessed by all three tasks. */ static QueueHandle_t xQueue; @@ -62,7 +68,7 @@ static void vSenderTask(void *pvParameters) vPrintString("Could not send to the queue!\n"); } - vTaskDelay(5000); + vTaskDelay(500); } } @@ -103,70 +109,77 @@ static void vReceiverTask(void *pvParameters) { if (xReceivedStructure.ucSource == mainSENDER_1) { + vTaskDelete(xtask1_handle); vPrintStringAndNumber("Received From Sender 1 = ", xReceivedStructure.ucValue); + xEventGroupSetBits(xEventGroup, FIRST_SENDER_TASK_BIT); } - else + else if (xReceivedStructure.ucSource == mainSENDER_2) { + vTaskDelete(xtask2_handle); vPrintStringAndNumber("Received From Sender 2 = ", xReceivedStructure.ucValue); + xEventGroupSetBits(xEventGroup, SECOND_SENDER_TASK_BIT); } } - else - { - /* We did not receive anything from the queue. This must be an error - as this task should only run when the queue is full. */ - vPrintString("Could not receive from the queue!\n"); - } } } -void CreateStructTasks(void) +static void DeleteStructTasks(void) +{ + if (xtask3_handle) + { + vTaskDelete(xtask3_handle); + vPrintString("Struct Receiver deletion."); + } +} + +BaseType_t CreateStructTasks(void) { BaseType_t ret; + EventBits_t xEventGroupValue; + const EventBits_t xBitsToWaitFor = (FIRST_SENDER_TASK_BIT | SECOND_SENDER_TASK_BIT); + xEventGroup = xEventGroupCreate(); /* The queue is created to hold a maximum of 3 structures of type xData. */ xQueue = xQueueCreate(3, sizeof(xData)); if (xQueue != NULL) { - ret = xTaskCreate(vReceiverTask, "Struct Receiver", TASK_STACK_SIZE, NULL, 2, &xtask1_handle); + ret = xTaskCreate(vSenderTask, "Struct Sender 1", TASK_STACK_SIZE, (void *) & (xStructsToSend[0]), 2, &xtask1_handle); if (ret != pdPASS) { xtask1_handle = NULL; - vPrintStringAndNumber("Receiver creation failed: ", ret); + vPrintStringAndNumber("Sender 1 creation failed: ", ret); + goto exit; } - ret = xTaskCreate(vSenderTask, "Struct Sender 1", TASK_STACK_SIZE, (void *) & (xStructsToSend[0]), 2, &xtask2_handle); + ret = xTaskCreate(vSenderTask, "Struct Sender 2", TASK_STACK_SIZE, (void *) & (xStructsToSend[1]), 2, &xtask2_handle); if (ret != pdPASS) { xtask2_handle = NULL; - vPrintStringAndNumber("Sender 1 creation failed: ", ret); + vPrintStringAndNumber("Sender 2 creation failed: ", ret); + goto exit; } - - ret = xTaskCreate(vSenderTask, "Struct Sender 2", TASK_STACK_SIZE, (void *) & (xStructsToSend[1]), 2, &xtask3_handle); + ret = xTaskCreate(vReceiverTask, "Struct Receiver", TASK_STACK_SIZE, NULL, 3, &xtask3_handle); if (ret != pdPASS) { xtask3_handle = NULL; - vPrintStringAndNumber("Sender 2 creation failed: ", ret); + vPrintStringAndNumber("Receiver creation failed: ", ret); + goto exit; } } -} + /* Block to wait for event bits to become set within the event group. */ + xEventGroupValue = xEventGroupWaitBits(xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, TIMER_OUT); -void DeleteStructTasks(void) -{ - if (xtask1_handle) - { - vTaskDelete(xtask1_handle); - vPrintString("Struct Receiver deletion \r\n"); - } +exit: + DeleteStructTasks(); - if (xtask2_handle) + if (xEventGroupValue != xBitsToWaitFor) { - vTaskDelete(xtask2_handle); - vPrintString("Struct Sender 1 deletion \r\n"); + vPrintf("%s@%d: Queue struct send then recv example [failure].\r\n", __func__, __LINE__); + return pdFAIL; } - - if (xtask3_handle) + else { - vTaskDelete(xtask3_handle); - vPrintString("Struct Sender 2 deletion \r\n"); + vPrintf("%s@%d: Queue struct send then recv example [success].\r\n", __func__, __LINE__); + return pdTRUE; } -} \ No newline at end of file +} diff --git a/example/freertos_feature/resource/README.md b/example/freertos_feature/resource/README.md index 25757181b25aec2084fc550e61770fb89c135df5..923efb1b62852382ffe444e0767253f53660d844 100644 --- a/example/freertos_feature/resource/README.md +++ b/example/freertos_feature/resource/README.md @@ -10,7 +10,7 @@ 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -79,12 +79,10 @@ bootelf -p 0x90100000 - 系统进入后,输入```resource```查看指令说明 - 输入```resource mutex_cre```,启动互斥信号量任务测试 -- 输入```resource mutex_del```,删除互斥信号量任务测试 ![mutex](./figs/resource_mutex.png) - 输入```resource gate_cre```,启动守护任务测试 -- 输入```resource gate_del```,删除守护任务测试 ![gate](./figs/resource_gate.png) diff --git a/example/freertos_feature/resource/figs/resource_gate.png b/example/freertos_feature/resource/figs/resource_gate.png index b0c053eb2f3cdd09efd4e33932a28d2d91c98b81..5e3651649e5e4fd52a9fd4b531abba8e2f6e8db3 100644 Binary files a/example/freertos_feature/resource/figs/resource_gate.png and b/example/freertos_feature/resource/figs/resource_gate.png differ diff --git a/example/freertos_feature/resource/figs/resource_mutex.png b/example/freertos_feature/resource/figs/resource_mutex.png index 5b4572f6a8b179d96094497772e39b69bb2ccb46..a018e92cad9c8a9f0bf3615c25c1dc88810a630c 100644 Binary files a/example/freertos_feature/resource/figs/resource_mutex.png and b/example/freertos_feature/resource/figs/resource_mutex.png differ diff --git a/example/freertos_feature/resource/inc/feature_resource.h b/example/freertos_feature/resource/inc/feature_resource.h index 83d1408819eecfa85d366dc9edfd4350704b1c07..962c0d93d8ef8b306f6fdffd98e097b10f86f928 100644 --- a/example/freertos_feature/resource/inc/feature_resource.h +++ b/example/freertos_feature/resource/inc/feature_resource.h @@ -13,13 +13,14 @@ * * FilePath: feature_resource.h * Date: 2022-06-17 10:42:40 - * LastEditTime: 2022-06-17 10:42:40 + * LastEditTime: 2024-05-07 10:42:40 * Description: This file is for task function define * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2022/08/09 first commit + * 1.1 huangjin 2024/05/07 add no letter shell mode, adapt to auto-test system */ #ifndef FEATURE_RESOURCE_H @@ -31,12 +32,9 @@ extern "C" #endif /* mutex task */ -void CreateResourceTasks(void); -void DeleteResourceTasks(void); - +int CreateResourceTasks(void); /* gatekeeper task */ -void CreateGatekeeperTasks(void); -void DeleteGatekeeperTasks(void); +int CreateGatekeeperTasks(void); #ifdef __cplusplus } diff --git a/example/freertos_feature/resource/main.c b/example/freertos_feature/resource/main.c index 9c8c87a20aa6ccf31c999e4e3dfc2dd7b1e49d3b..8647fc91f50c1a1a473529b3d73e22cab3170754 100644 --- a/example/freertos_feature/resource/main.c +++ b/example/freertos_feature/resource/main.c @@ -13,33 +13,65 @@ * * FilePath: main.c * Date: 2022-06-17 08:17:59 - * LastEditTime: 2022-06-17 08:17:59 + * LastEditTime: 2024-05-07 08:17:59 * Description: This file is for resource example that running shell task and open scheduler * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2022/08/09 first commit + * 1.1 huangjin 2024/05/07 add no letter shell mode, adapt to auto-test system */ +#include +#include "FreeRTOS.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include +#else +#include "task.h" +#include "feature_resource.h" + + +#define FEATURE_RESOUCE_EXAMPLE_TASK_PRIORITY 2 + +void FeatureResourceExampleTaskEntry(void *pvParameters) +{ + /* example functions */ + CreateResourceTasks(); + CreateGatekeeperTasks(); + + /* end flag */ + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif int main(void) { - BaseType_t ret; + BaseType_t ret = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - ret = LSUserShellTask() ; +#ifdef CONFIG_USE_LETTER_SHELL + ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)FeatureResourceExampleTaskEntry, /* 任务入口函数 */ + (const char *)"FeatureResourceExampleTaskEntry",/* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)FEATURE_RESOUCE_EXAMPLE_TASK_PRIORITY, /* 任务的优先级 */ + NULL); +#endif if (ret != pdPASS) { goto FAIL_EXIT; } - + vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("failed 0x%x. \r\n", ret); - return 0; + printf("Feature resource example failed in main.c, the ret value is 0x%x. \r\n", ret); + return -2; } diff --git a/example/freertos_feature/resource/src/gatekeeper.c b/example/freertos_feature/resource/src/gatekeeper.c index 747e751c1c8f96d8fc0b90f1d6e26598cc89288b..018c725a981c297e7505612b3c3b4d7c9fae2b0b 100644 --- a/example/freertos_feature/resource/src/gatekeeper.c +++ b/example/freertos_feature/resource/src/gatekeeper.c @@ -10,11 +10,26 @@ Re-writing vPrintString() to use a gatekeeper task. #include "task.h" #include "queue.h" -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 +#define QUEUE_LENGTH 1 +#define PRINT_QUEUE_LENGTH 5 +#define PRINT_1_TASK_PARAM (void *)0 +#define PRINT_2_TASK_PARAM (void *)1 +#define PRINT_1_TASK_PRIORITY 3 +#define PRINT_2_TASK_PRIORITY 4 +#define PRINT_GATEKEEPER_TASK_PRIORITY 1 +#define PRINT_TIMES 4 +#define GATEKEEPER_RECV_TIMES 10 +#define GATEKEEPER_EXAMPLE_TIMEOUT pdMS_TO_TICKS(30000U) +#define GATEKEEPER_RECV_TIMEOUT pdMS_TO_TICKS(3000U) -static xTaskHandle xtask1_handle; -static xTaskHandle xtask2_handle; -static xTaskHandle xtask3_handle; +enum +{ + GATEKEEPER_EXAMPLE_SUCCESS = 0, + GATEKEEPER_EXAMPLE_UNKNOWN_STATE, + GATEKEEPER_EXAMPLE_QUEUE_CREATE_FAILURE, + GATEKEEPER_EXAMPLE_FAILURE, +}; static char *pcStringsToPrint[] = { @@ -23,28 +38,52 @@ static char *pcStringsToPrint[] = "Gatekeep Message printed from the tick hook #####\n" }; -xQueueHandle xPrintQueue; +static xQueueHandle xPrintQueue; +static QueueHandle_t xQueue = NULL; static void prvStdioGatekeeperTask(void *pvParameters) { + int task_res = GATEKEEPER_EXAMPLE_UNKNOWN_STATE; + BaseType_t xReturn = pdPASS; + int iRecvTimes = 0; char *pcMessageToPrint; for (;;) { - xQueueReceive(xPrintQueue, &pcMessageToPrint, portMAX_DELAY); + xQueueReceive(xPrintQueue, &pcMessageToPrint, GATEKEEPER_RECV_TIMEOUT); + if (xReturn == pdFAIL) + { + vPrintString("xPrintQueue receive timeout."); + break; + } + else + { + iRecvTimes++; + } printf( "%s", pcMessageToPrint ); + if (iRecvTimes == GATEKEEPER_RECV_TIMES) + { + task_res = GATEKEEPER_EXAMPLE_SUCCESS; + xQueueSend(xQueue, &task_res, 0); + break; + } } + + vTaskDelete(NULL); } static void prvPrintTask(void *pvParameters) { int iIndexToString; iIndexToString = (int)(uintptr)pvParameters; + const TickType_t xDelay = pdMS_TO_TICKS(1000UL); - for (;;) + for (int loop = 0; loop < PRINT_TIMES; loop++) { xQueueSendToBack(xPrintQueue, &(pcStringsToPrint[iIndexToString]), 0); - vTaskDelay(5000); + vTaskDelay(xDelay); } + + vTaskDelete(NULL); } void vApplicationTickHook(void) @@ -60,40 +99,64 @@ void vApplicationTickHook(void) { xQueueSendToFrontFromISR(xPrintQueue, &(pcStringsToPrint[2]), - &xHigherPriorityTaskWoken); // not needed + &xHigherPriorityTaskWoken); /* not needed */ iCount = 0; } } -void CreateGatekeeperTasks(void) +int CreateGatekeeperTasks(void) { - xPrintQueue = xQueueCreate(5, sizeof(char *)); + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = GATEKEEPER_EXAMPLE_UNKNOWN_STATE; - if (xPrintQueue != NULL) + xQueue = xQueueCreate(QUEUE_LENGTH, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) { - xTaskCreate(prvPrintTask, "Gatekeeper Print1", TASK_STACK_SIZE, (void *)0, 1, &xtask1_handle); - xTaskCreate(prvPrintTask, "Gatekeeper Print2", TASK_STACK_SIZE, (void *)1, 2, &xtask2_handle); - xTaskCreate(prvStdioGatekeeperTask, "Gatekeeper", TASK_STACK_SIZE, NULL, 0, &xtask3_handle); + vPrintString("xQueue create failed."); + task_res = GATEKEEPER_EXAMPLE_QUEUE_CREATE_FAILURE; + goto exit; } -} -void DeleteGatekeeperTasks(void) -{ - if (xtask1_handle) + xPrintQueue = xQueueCreate(PRINT_QUEUE_LENGTH, sizeof(char *)); + if (xPrintQueue == NULL) + { + vPrintString("xPrintQueue create failed."); + task_res = GATEKEEPER_EXAMPLE_QUEUE_CREATE_FAILURE; + goto exit; + } + else + { + xTaskCreate(prvPrintTask, "Gatekeeper Print1", TASK_STACK_SIZE, PRINT_1_TASK_PARAM, PRINT_1_TASK_PRIORITY, NULL); + xTaskCreate(prvPrintTask, "Gatekeeper Print2", TASK_STACK_SIZE, PRINT_2_TASK_PARAM, PRINT_2_TASK_PRIORITY, NULL); + xTaskCreate(prvStdioGatekeeperTask, "Gatekeeper", TASK_STACK_SIZE, NULL, PRINT_GATEKEEPER_TASK_PRIORITY, NULL); + } + + xReturn = xQueueReceive(xQueue, &task_res, GATEKEEPER_EXAMPLE_TIMEOUT); + if (xReturn == pdFAIL) + { + vPrintString("xQueue receive timeout."); + goto exit; + } + +exit: + if (xQueue != NULL) { - vTaskDelete(xtask1_handle); - vPrintString("Gatekeeper Print1 deletion \r\n"); + vQueueDelete(xQueue); } - if (xtask2_handle) + if (xPrintQueue != NULL) { - vTaskDelete(xtask2_handle); - vPrintString("Gatekeeper Print2 deletion \r\n"); + vQueueDelete(xPrintQueue); } - if (xtask3_handle) + if (task_res != GATEKEEPER_EXAMPLE_SUCCESS) + { + vPrintString("Resource Gatekeeper feature example [failure]"); + return task_res; + } + else { - vTaskDelete(xtask3_handle); - vPrintString("Gatekeeper deletion \r\n"); + vPrintString("Resource Gatekeeper feature example [success]."); + return task_res; } } \ No newline at end of file diff --git a/example/freertos_feature/resource/src/mutex.c b/example/freertos_feature/resource/src/mutex.c index fc5dc5b3dfa5b8585d504488f893e0bb93c2c8de..8c2e1664c84e3030d3096baa2ee8fcbea011292b 100644 --- a/example/freertos_feature/resource/src/mutex.c +++ b/example/freertos_feature/resource/src/mutex.c @@ -11,65 +11,113 @@ Rewriting vPrintString() to use a mutex semaphore. #include "semphr.h" #include "croutine.h" -#define TASK_STACK_SIZE 1024 +#define TASK_STACK_SIZE 1024 +#define QUEUE_LENGTH 1 +#define PRINT_1_TASK_PARAM (void *)0 +#define PRINT_2_TASK_PARAM (void *)1 +#define PRINT_1_TASK_PRIORITY 3 +#define PRINT_2_TASK_PRIORITY 4 +#define MUTEX_PRINT_TIMES 4 +#define MUTEX_EXAMPLE_TIMEOUT pdMS_TO_TICKS(5000U) +#define MUTEX_TAKE_TIMEOUT pdMS_TO_TICKS(2000U) + +enum +{ + MUTEX_EXAMPLE_SUCCESS = 0, + MUTEX_EXAMPLE_UNKNOWN_STATE, + MUTEX_EXAMPLE_QUEUE_CREATE_FAILURE, + MUTEX_EXAMPLE_FAILURE, +}; -static xTaskHandle xtask1_handle; -static xTaskHandle xtask2_handle; +static char *pcStringsToPrint[] = +{ + "Task 1 ******************************\n", + "Task 2 ==============================\n" +}; static xSemaphoreHandle xMutex; +static QueueHandle_t xQueue = NULL; -static void prvNewPrintString(const char *pcString) +static void prvMutexPrintString(const char *pcString) { - xSemaphoreTake(xMutex, portMAX_DELAY); - printf("Mutex pcString = %s\n", pcString); + xSemaphoreTake(xMutex, MUTEX_TAKE_TIMEOUT); + printf("Mutex pcString = %s", pcString); xSemaphoreGive(xMutex); } static void prvPrintTask(void *pvParameters) { - char *pcStringToPrint; - pcStringToPrint = (char *)pvParameters; + int task_res = MUTEX_EXAMPLE_UNKNOWN_STATE; + int print_time = 0; + int iIndexToString = (int)(uintptr)pvParameters; + const TickType_t xDelay = pdMS_TO_TICKS(1000UL); - for (;;) + for (int loop = 0; loop < MUTEX_PRINT_TIMES; loop++) { - prvNewPrintString(pcStringToPrint); + prvMutexPrintString(pcStringsToPrint[iIndexToString]); + print_time++; /* Just delay with random time, Don't use rand() in secure applications. It's not reentrant!*/ - vTaskDelay(/*rand() & 0x3FF*/5000); + vTaskDelay(/*rand() & 0x3FF*/xDelay); + } + + if ((print_time == MUTEX_PRINT_TIMES) && (pvParameters == PRINT_2_TASK_PARAM)) + { + task_res = MUTEX_EXAMPLE_SUCCESS; + xQueueSend(xQueue, &task_res, 0); } + + vTaskDelete(NULL); } -void CreateResourceTasks(void) +int CreateResourceTasks(void) { + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = MUTEX_EXAMPLE_UNKNOWN_STATE; + + xQueue = xQueueCreate(QUEUE_LENGTH, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) + { + vPrintString("xQueue create failed."); + task_res = MUTEX_EXAMPLE_QUEUE_CREATE_FAILURE; + goto exit; + } xMutex = xSemaphoreCreateMutex(); if (xMutex != NULL) { - - xTaskCreate(prvPrintTask, "Mutex Print1", TASK_STACK_SIZE, - "Task 1 ******************************\n", 1, &xtask1_handle); - xTaskCreate(prvPrintTask, "Mutex Print2", TASK_STACK_SIZE, - "Task 2 ==============================\n", 2, &xtask2_handle); + xTaskCreate(prvPrintTask, "Mutex Print1", TASK_STACK_SIZE, PRINT_1_TASK_PARAM, PRINT_1_TASK_PRIORITY, NULL); + xTaskCreate(prvPrintTask, "Mutex Print2", TASK_STACK_SIZE, PRINT_2_TASK_PARAM, PRINT_2_TASK_PRIORITY, NULL); } -} - -void DeleteResourceTasks(void) -{ - if (xtask1_handle) + xReturn = xQueueReceive(xQueue, &task_res, MUTEX_EXAMPLE_TIMEOUT); + if (xReturn == pdFAIL) { - vTaskDelete(xtask1_handle); - printf("Resource Task1 deletion \r\n"); + vPrintString("xQueue receive timeout."); + goto exit; } - if (xtask2_handle) +exit: + if (xQueue != NULL) { - vTaskDelete(xtask2_handle); - printf("Resource Task2 deletion \r\n"); + vQueueDelete(xQueue); } - vSemaphoreDelete(xMutex); -} + if (xMutex != NULL) + { + vSemaphoreDelete(xMutex); + } + if (task_res != MUTEX_EXAMPLE_SUCCESS) + { + vPrintString("Resource mutex feature example [failure]"); + return task_res; + } + else + { + vPrintString("Resource mutex feature example [success]."); + return task_res; + } +} \ No newline at end of file diff --git a/example/freertos_feature/resource/src/resource_cmd.c b/example/freertos_feature/resource/src/resource_cmd.c index 0d2e009aa6e605d7418d93bf4453ea11587fd290..23564704ad3e8c474a2522293b674e124c9d7403 100644 --- a/example/freertos_feature/resource/src/resource_cmd.c +++ b/example/freertos_feature/resource/src/resource_cmd.c @@ -13,43 +13,37 @@ * * FilePath: resource_cmd.c * Date: 2022-06-17 10:41:45 - * LastEditTime: 2022-06-17 10:41:45 + * LastEditTime: 2024-05-07 10:41:45 * Description: This file is for resource command interface * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2022/08/09 first commit + * 1.1 huangjin 2024/05/07 add no letter shell mode, adapt to auto-test system */ -#include "shell.h" +#include "sdkconfig.h" +#include "FreeRTOS.h" #include "feature_resource.h" #include +#include "task.h" #include - -typedef enum -{ - MUTEX_TASK_INDEX = 0, - GATEKEEPER_TEST_INDEX = 1, - RESOURCE_FEATURE_LENGTH -} FreeRtosResourceFeatureSelect; +#include "strto.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "../src/shell.h" static void ResourceTasksCmdUsage(void) { printf("Usage:\r\n"); - printf(" resource mutex_cre \r\n"); - printf(" -- Create mutex tasks now. \r\n"); - printf(" resource mutex_del \r\n"); - printf(" -- Del mutex tasks now. \r\n"); - printf(" resource gate_cre \r\n"); - printf(" -- Create gatekeeper tasks now. \r\n"); - printf(" resource gate_del \r\n"); - printf(" -- Del gatekeeper tasks now. \r\n"); - + printf("resource mutex_cre \r\n"); + printf("-- Create mutex tasks now. \r\n"); + printf("resource gate_cre \r\n"); + printf("-- Create gatekeeper tasks now. \r\n"); } int ResourceTasksCmd(int argc, char *argv[]) { - static int create_flg[RESOURCE_FEATURE_LENGTH] = {0}; /* 1 is tasks has been created*/ + int ret = 0; if (argc < 2) { @@ -59,51 +53,11 @@ int ResourceTasksCmd(int argc, char *argv[]) if (!strcmp(argv[1], "mutex_cre")) { - if (create_flg[MUTEX_TASK_INDEX] == 0) - { - CreateResourceTasks(); - create_flg[MUTEX_TASK_INDEX] = 1; - } - else - { - printf("Please use mutex_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "mutex_del")) - { - if (create_flg[MUTEX_TASK_INDEX] == 1) - { - DeleteResourceTasks(); - create_flg[MUTEX_TASK_INDEX] = 0; - } - else - { - printf("Please use mutex_cre cmd first. \r\n"); - } + ret = CreateResourceTasks(); } else if (!strcmp(argv[1], "gate_cre")) { - if (create_flg[GATEKEEPER_TEST_INDEX] == 0) - { - CreateGatekeeperTasks(); - create_flg[GATEKEEPER_TEST_INDEX] = 1; - } - else - { - printf("Please use gate_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "gate_del")) - { - if (create_flg[GATEKEEPER_TEST_INDEX] == 1) - { - DeleteGatekeeperTasks(); - create_flg[GATEKEEPER_TEST_INDEX] = 0; - } - else - { - printf("Please use gate_cre cmd first. \r\n"); - } + ret = CreateGatekeeperTasks(); } else { @@ -114,5 +68,4 @@ int ResourceTasksCmd(int argc, char *argv[]) } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), resource, ResourceTasksCmd, Resource Management test); - - +#endif \ No newline at end of file diff --git a/example/freertos_feature/software_timer/README.md b/example/freertos_feature/software_timer/README.md index 294f648c0cb990d3f0d1a182feedf1077b4021b8..59dce8cf8560aaaaf8d24a677efdafed78b98206 100644 --- a/example/freertos_feature/software_timer/README.md +++ b/example/freertos_feature/software_timer/README.md @@ -12,7 +12,7 @@ FreeRTOS 提供的软件定时器支持单次模式和周期模式; 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -43,13 +43,13 @@ FreeRTOS 提供的软件定时器支持单次模式和周期模式; - CONFIG_USE_LETTER_SHELL 本例子已经提供好具体的编译指令,以下进行介绍: -- make 将目录下的工程进行编译 -- make clean 将目录下的工程进行清理 -- make image 将目录下的工程进行编译,并将生成的elf 复制到目标地址 -- make list_kconfig 当前工程支持哪些配置文件 -- make load_kconfig LOAD_CONFIG_NAME= 将预设配置加载至工程中 -- make menuconfig 配置目录下的参数变量 -- make backup_kconfig 将目录下的sdkconfig 备份到./configs下 +- make 将目录下的工程进行编译 +- make clean 将目录下的工程进行清理 +- make image 将目录下的工程进行编译,并将生成的elf 复制到目标地址 +- make list_kconfig 当前工程支持哪些配置文件 +- make load_kconfig LOAD_CONFIG_NAME= 将预设配置加载至工程中 +- make menuconfig 配置目录下的参数变量 +- make backup_kconfig 将目录下的sdkconfig 备份到./configs下 具体使用方法为: - 在当前目录下 @@ -80,13 +80,11 @@ bootelf -p 0x90100000 ### 2.4 输出与实验现象 - 系统进入后,输入```timer```查看指令说明 -- 输入```timer cre```,启动创建、使能定时器测试 -- 输入```timer del```,删除创建、使能定时器测试 +- 输入```timer create_start_example```,启动创建、使能定时器测试 ![cre](./figs/timer_cre.png) -- 输入```timer reset_cre```,启动定时器复位、设置id测试 -- 输入```timer reset_del```,删除定时器复位、设置id测试 +- 输入```timer id_reset_example```,启动定时器复位、设置id测试 ![reset](./figs/timer_reset.png) diff --git a/example/freertos_feature/software_timer/figs/timer_cre.png b/example/freertos_feature/software_timer/figs/timer_cre.png index 7702560b49ab487750fa6fdb2c8027688ff1a7fe..2d5a216da1b66dc5f9314879106003afced5c790 100644 Binary files a/example/freertos_feature/software_timer/figs/timer_cre.png and b/example/freertos_feature/software_timer/figs/timer_cre.png differ diff --git a/example/freertos_feature/software_timer/figs/timer_reset.png b/example/freertos_feature/software_timer/figs/timer_reset.png index c6d1928b2e2a0dce5ebf79aed11a59e2027a7217..24ca0db4925e9e2a8c0ec5ea28e8709c2b11f3de 100644 Binary files a/example/freertos_feature/software_timer/figs/timer_reset.png and b/example/freertos_feature/software_timer/figs/timer_reset.png differ diff --git a/example/freertos_feature/software_timer/inc/feature_software_timer.h b/example/freertos_feature/software_timer/inc/feature_software_timer.h index 2dfd3f03a3e193a5577451d78dd9e0586795722b..bb853cffd5229fa22dec7c9fcbfe20fb4bf626a2 100644 --- a/example/freertos_feature/software_timer/inc/feature_software_timer.h +++ b/example/freertos_feature/software_timer/inc/feature_software_timer.h @@ -17,12 +17,12 @@ * Description: This file is for task function define * * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - * 1.0 wangxiaodong 2022/08/09 first commit + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first commit + * 2.0 liqiaozhong 2024/5/7 add no letter shell mode, adapt to auto-test system */ - #ifndef FEATURE_SOFTWARE_TIMER_H #define FEATURE_SOFTWARE_TIMER_H @@ -31,12 +31,8 @@ extern "C" { #endif -/* software timer create and start */ -void CreateTimerTasks(void); -void DeleteTimerTasks(void); - -void CreateTimerResetTasks(void); -void DeleteTimerResetTasks(void); +int CreateTimerTasks(void); +int CreateTimerResetTasks(void); #ifdef __cplusplus } diff --git a/example/freertos_feature/software_timer/main.c b/example/freertos_feature/software_timer/main.c index c1ab62ef8c4a1f2306608d66af9aa35394a22390..9cc5876fd534c1d30d3edb6672e53de6fd3d5610 100644 --- a/example/freertos_feature/software_timer/main.c +++ b/example/freertos_feature/software_timer/main.c @@ -17,20 +17,49 @@ * Description: This file is for software_timer example that running shell task and open scheduler * * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - * 1.0 wangxiaodong 2022/08/09 first commit + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first commit + * 2.0 liqiaozhong 2024/5/7 add no letter shell mode, adapt to auto-test system */ +#include + +#include "FreeRTOS.h" + +#include "sdkconfig.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include +#else +#include "task.h" +#include "feature_software_timer.h" +#define SOFTWARE_TIMER_EXAMPLE_TASK_PRIORITY 2 +void SoftwareTimerExampleTaskEntry() +{ + CreateTimerTasks(); + CreateTimerResetTasks(); + + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif int main(void) { - BaseType_t ret; - - ret = LSUserShellTask() ; + BaseType_t ret = pdPASS; /* Define a return value with a default of pdPASS */ +#ifdef CONFIG_USE_LETTER_SHELL + ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)SoftwareTimerExampleTaskEntry, + (const char *)"SoftwareTimerExampleTaskEntry", + (uint16_t)4096, + NULL, + (UBaseType_t)SOFTWARE_TIMER_EXAMPLE_TASK_PRIORITY, + NULL); +#endif if (ret != pdPASS) { goto FAIL_EXIT; @@ -40,6 +69,6 @@ int main(void) while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("failed 0x%x. \r\n", ret); - return 0; -} + printf("Software timer example failed in main.c, the ret value is 0x%x. \r\n", ret); + return -2; +} \ No newline at end of file diff --git a/example/freertos_feature/software_timer/src/create_start.c b/example/freertos_feature/software_timer/src/create_start.c index ffccee0386bdd06ffd4b90b28098a7b5243026fc..a03bfdc36669b6370ed47afa2376b100b2fb8dcd 100644 --- a/example/freertos_feature/software_timer/src/create_start.c +++ b/example/freertos_feature/software_timer/src/create_start.c @@ -1,130 +1,166 @@ -/* -This example demonstrates: -creates and starts a one-shot timer and an auto-reload timer in diffirent period. -*/ +/* This example demonstrates: + creates and starts a one-shot timer and an auto-reload timer in diffirent period. + */ #include "FreeRTOS.h" #include "task.h" +#include "queue.h" #include "timers.h" +#define AUTO_RELOAD_TIMES 3 +#define TIMER_TASK_NUM 2 +#define EXAMPLE_TIMEOUT (pdMS_TO_TICKS(30000UL)) + /* The periods assigned to the one-shot and auto-reload timers respectively. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 3000UL ) ) -#define AUTO_RELOAD_TIMER_PERIOD ( pdMS_TO_TICKS( 3000UL ) ) +#define ONE_SHOT_TIMER_PERIOD (pdMS_TO_TICKS(3000UL)) +#define AUTO_RELOAD_TIMER_PERIOD (pdMS_TO_TICKS(3000UL)) + +#define ONE_SHOT_SUCCESS_BIT (1UL << 0UL) /* bit 0, which is set by one-shot task. */ +#define AUTO_RELOAD_SUCCESS_BIT (1UL << 1UL) /* bit 1, which is set by auto-reload task. */ + +static QueueHandle_t xQueue = NULL; +static TimerHandle_t xOneShotTimer; +static TimerHandle_t xAutoReloadTimer; /*-----------------------------------------------------------*/ +/* The callback functions used by the one-shot and auto-reload timers respectively. */ +static void prvOneShotTimerCallback(TimerHandle_t xTimer) +{ + static TickType_t xTimeNow; + BaseType_t xReturn = pdFAIL; + u32 task_res = 0; -/* - * The callback functions used by the one-shot and auto-reload timers - * respectively. - */ -static void prvOneShotTimerCallback(TimerHandle_t xTimer); -static void prvAutoReloadTimerCallback(TimerHandle_t xTimer); + /* Obtain the current tick count. */ + xTimeNow = xTaskGetTickCount(); + + /* Output a string to show the time at which the callback was executed. */ + vPrintf("One-shot timer callback executing once, and now_ticks: %d \r\n", xTimeNow); + + xReturn = xTimerDelete(xOneShotTimer, 0); + if (xReturn != pdPASS) + { + vPrintf("DeleteSoftwareTimerTasks xTimerDelete OneShot failed.\r\n"); + } + else + { + vPrintf("Delete software timer one-shot task.\r\n"); + task_res = ONE_SHOT_SUCCESS_BIT; + xQueueSend(xQueue, &task_res, 0); + } +} /*-----------------------------------------------------------*/ -static TimerHandle_t xAutoReloadTimer, xOneShotTimer; -void CreateTimerTasks(void) +static void prvAutoReloadTimerCallback(TimerHandle_t xTimer) { + static TickType_t xTimeNow; + static int auto_timer_times = 0; /* Tracking the number of callback executions */ + BaseType_t xReturn = pdFAIL; + u32 task_res = 0; + + /* Obtain the current tick count. */ + xTimeNow = xTaskGetTickCount(); + + /* Output a string to show the time at which the callback was executed. */ + vPrintf("Auto-reload timer callback executing for %d time(s), and now_ticks: %d \r\n", ++auto_timer_times, xTimeNow); + + if (auto_timer_times >= 3) + { + xReturn = xTimerDelete(xAutoReloadTimer, 0); + if (xReturn != pdPASS) + { + vPrintf("DeleteSoftwareTimerTasks xTimerDelete AutoReload failed.\r\n"); + } + else + { + vPrintf("Delete software timer auto-reload task.\r\n"); + task_res = AUTO_RELOAD_SUCCESS_BIT; + xQueueSend(xQueue, &task_res, 0); + } + } +} - BaseType_t xTimer1Started, xTimer2Started; +/*-----------------------------------------------------------*/ - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate("Create OneShot", /* Text name for the software timer - not used by FreeRTOS. */ +int CreateTimerTasks(void) +{ + BaseType_t xTimer1Started; + BaseType_t xTimer2Started; + BaseType_t xReturn = pdPASS; /* Define a return value with a default of pdPASS */ + u32 task_res = 0; + u32 task_flag = 0; + + xQueue = xQueueCreate(2, sizeof(u32)); /* Create Message Queue */ + if (xQueue == NULL) + { + vPrintf("xQueue create failed. \r\n"); + goto exit; + } + + /* Create the one shot software timer, storing the handle to the created software timer in xOneShotTimer. */ + xOneShotTimer = xTimerCreate("Create OneShot", /* Text name for the software timer - not used by FreeRTOS. */ ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example does not use the timer id. */ - prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ - - /* Create the auto-reload software timer, storing the handle to the created - software timer in xAutoReloadTimer. */ - xAutoReloadTimer = xTimerCreate("Create AutoReload", /* Text name for the software timer - not used by FreeRTOS. */ - AUTO_RELOAD_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload software timer. */ - 0, /* This example does not use the timer id. */ - prvAutoReloadTimerCallback); /* The callback function to be used by the software timer being created. */ + pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ + 0, /* This example does not use the timer id. */ + prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ + + /* Create the auto-reload software timer, storing the handle to the created software timer in xAutoReloadTimer. */ + xAutoReloadTimer = xTimerCreate("Create AutoReload", /* Text name for the software timer - not used by FreeRTOS. */ + AUTO_RELOAD_TIMER_PERIOD, /* The software timer's period in ticks. */ + pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload software timer. */ + 0, /* This example does not use the timer id. */ + prvAutoReloadTimerCallback); /* The callback function to be used by the software timer being created. */ /* Check the timers were created. */ if ((xOneShotTimer != NULL) && (xAutoReloadTimer != NULL)) { /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ + * The scheduler has not been started yet so any block time specified here would be ignored anyway. + */ xTimer1Started = xTimerStart(xOneShotTimer, 0); xTimer2Started = xTimerStart(xAutoReloadTimer, 0); - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ + /* The implementation of xTimerStart() uses the timer command queue, and xTimerStart() will fail if the timer command queue gets full. + * The timer service task does not get created until the scheduler is started, + so all commands sent to the command queue will stay in the queue until after the scheduler has been started. + * Check both calls to xTimerStart() passed. + */ if ((xTimer1Started != pdPASS) || (xTimer2Started != pdPASS)) { vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); + goto exit; } } else { vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); + goto exit; } -} - -void DeleteTimerTasks(void) -{ - BaseType_t xReturn = pdFAIL; - xReturn = xTimerDelete(xOneShotTimer, 0); - if (xReturn != pdPASS) + for (int loop = 0; loop < TIMER_TASK_NUM; loop++) { - vPrintf("DeleteSoftwareTimerTasks xTimerDelete OneShot failed.\r\n"); + xReturn = xQueueReceive(xQueue, &task_res, EXAMPLE_TIMEOUT); + if (xReturn == pdFAIL) + { + vPrintString("xQueue receive timeout or task err."); + goto exit; + } + task_flag |= task_res; } - else + +exit: + if (xQueue != NULL) { - vPrintf("DeleteSoftwareTimerTasks xTimerDelete OneShot success.\r\n"); + vQueueDelete(xQueue); } - xReturn = xTimerDelete(xAutoReloadTimer, 0); - if (xReturn != pdPASS) + if (task_flag != (ONE_SHOT_SUCCESS_BIT | AUTO_RELOAD_SUCCESS_BIT)) { - vPrintf("DeleteSoftwareTimerTasks xTimerDelete AutoReload failed.\r\n"); + vPrintf("%s@%d: Software timer create start example [failure], task_flag = 0x%x \r\n", __func__, __LINE__, task_flag); + return -1; } else { - vPrintf("DeleteSoftwareTimerTasks xTimerDelete AutoReload success.\r\n"); + vPrintf("%s@%d: Software timer create start example [success].\r\n", __func__, __LINE__); + return 0; } -} - - -/*-----------------------------------------------------------*/ - -static void prvOneShotTimerCallback(TimerHandle_t xTimer) -{ - static TickType_t xTimeNow; - - /* Obtain the current tick count. */ - xTimeNow = xTaskGetTickCount(); - - /* Output a string to show the time at which the callback was executed. */ - vPrintf("One-shot timer callback executing %d ticks.\r\n", xTimeNow); -} -/*-----------------------------------------------------------*/ - -static void prvAutoReloadTimerCallback(TimerHandle_t xTimer) -{ - static TickType_t xTimeNow; - - /* Obtain the current tick count. */ - xTimeNow = xTaskGetTickCount(); - - /* Output a string to show the time at which the callback was executed. */ - vPrintf("Auto-reload timer callback executing %d ticks.\r\n", xTimeNow); -} -/*-----------------------------------------------------------*/ - - - - - - - - +} \ No newline at end of file diff --git a/example/freertos_feature/software_timer/src/software_timer_cmd.c b/example/freertos_feature/software_timer/src/software_timer_cmd.c index c5e0904ac5b98e2f5fd53a8b8d7a4e8ea2e3e0ef..f8b0c933fd0c69d782cacfa33aa638539464b3aa 100644 --- a/example/freertos_feature/software_timer/src/software_timer_cmd.c +++ b/example/freertos_feature/software_timer/src/software_timer_cmd.c @@ -17,93 +17,46 @@ * Description: This file is for software timer command interface * * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - * 1.0 wangxiaodong 2022/08/09 first commit + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 wangxiaodong 2022/8/9 first commit + * 2.0 liqiaozhong 2024/5/7 add no letter shell mode, adapt to auto-test system */ -#include "shell.h" + #include #include -#include "feature_software_timer.h" -typedef enum -{ - CREATE_START_TASK_INDEX = 0, - TIMER_ID_TASK_INDEX = 1, - SOFTWARE_TIMER_FEATURE_LENGTH -} FreeRtosSoftTimerFeatureSelect; +#include "sdkconfig.h" + +#ifdef CONFIG_USE_LETTER_SHELL +#include "../src/shell.h" + +#include "feature_software_timer.h" static void SoftwareTimerCmdUsage(void) { printf("Usage:\r\n"); - printf(" timer cre \r\n"); - printf(" -- Create and starts a one-shot timer and an auto-reload timer.\r\n"); - printf(" timer del \r\n"); - printf(" -- Delete and starts a one-shot timer and an auto-reload timer.\r\n"); - printf(" timer reset_cre \r\n"); - printf(" -- Create software timer use timer id and reset timer.\r\n"); - printf(" timer reset_del \r\n"); - printf(" -- Del software timer use timer id and reset timer.\r\n"); - + printf("timer create_start_example \r\n"); + printf("-- Create and starts a one-shot timer and an auto-reload timer.\r\n"); + printf("timer id_reset_example \r\n"); + printf("-- Create software timer use timer id and reset timer.\r\n"); } int SoftwareTimerCmd(int argc, char *argv[]) { - static int create_flg[SOFTWARE_TIMER_FEATURE_LENGTH] = {0}; /* 1 is tasks has been created*/ - if (argc < 2) { SoftwareTimerCmdUsage(); return -1; } - if (!strcmp(argv[1], "cre")) - { - if (create_flg[CREATE_START_TASK_INDEX] == 0) - { - CreateTimerTasks(); - create_flg[CREATE_START_TASK_INDEX] = 1; - } - else - { - printf("Please use del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "del")) + if (!strcmp(argv[1], "create_start_example")) { - if (create_flg[CREATE_START_TASK_INDEX] == 1) - { - DeleteTimerTasks(); - create_flg[CREATE_START_TASK_INDEX] = 0; - } - else - { - printf("Please use cre cmd first. \r\n"); - } + CreateTimerTasks(); } - else if (!strcmp(argv[1], "reset_cre")) + else if (!strcmp(argv[1], "id_reset_example")) { - if (create_flg[TIMER_ID_TASK_INDEX] == 0) - { - CreateTimerResetTasks(); - create_flg[TIMER_ID_TASK_INDEX] = 1; - } - else - { - printf("Please use reset_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "reset_del")) - { - if (create_flg[TIMER_ID_TASK_INDEX] == 1) - { - DeleteTimerResetTasks(); - create_flg[TIMER_ID_TASK_INDEX] = 0; - } - else - { - printf("Please use reset_cre cmd first. \r\n"); - } + CreateTimerResetTasks(); } else { @@ -114,5 +67,4 @@ int SoftwareTimerCmd(int argc, char *argv[]) } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), timer, SoftwareTimerCmd, software timer test); - - +#endif \ No newline at end of file diff --git a/example/freertos_feature/software_timer/src/timer_id_and_reset.c b/example/freertos_feature/software_timer/src/timer_id_and_reset.c index bbd32f442f42d33ec5231b66f86e3aa3eefc4d56..c54d033355fb1f9e75db6eb8a329109e70edff2f 100644 --- a/example/freertos_feature/software_timer/src/timer_id_and_reset.c +++ b/example/freertos_feature/software_timer/src/timer_id_and_reset.c @@ -1,147 +1,197 @@ -/* -This example demonstrates: -how to use the software timer ID as timer specific storage; -each software timer keeps a count of the number of times it has expired in its own ID; -Auto reload timer will stop after it has executed 5 times which period is 1000, -when the one shot timer is run after 9333 ticks, it will reset auto reload timer. -*/ +/* This example demonstrates: + how to use the software timer ID as timer specific storage; + each software timer keeps a count of the number of times it has expired in its own ID; + Auto reload timer will stop after it has executed 5 times which period is 1000, when the one shot timer is run after 9333 ticks, it will reset auto reload timer. + */ #include "FreeRTOS.h" #include "task.h" +#include "queue.h" #include "timers.h" /* The periods assigned to the one-shot and auto-reload timers respectively. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 12000UL ) ) -#define AUTO_RELOAD_TIMER_PERIOD ( pdMS_TO_TICKS( 3000UL ) ) +#define ONE_SHOT_TIMER_PERIOD (pdMS_TO_TICKS(9000UL)) +#define AUTO_RELOAD_TIMER_PERIOD (pdMS_TO_TICKS(2000UL)) -/*-----------------------------------------------------------*/ +#define EXAMPLE_TIMEOUT (pdMS_TO_TICKS(20000UL)) + +enum +{ + EXAMPLE_SUCCESS = 0, + UNKNOWN_STATE, + EXAMPLE_FAILURE, +}; + +static QueueHandle_t xQueue = NULL; +static TimerHandle_t xOneShotTimer; +static TimerHandle_t xAutoReloadTimer; +/*-----------------------------------------------------------*/ /* * The callback function that is used by both timers. */ -static void prvTimerCallback(TimerHandle_t xTimer); - -/*-----------------------------------------------------------*/ +static void prvTimerCallback(TimerHandle_t xTimer) +{ + BaseType_t xReturn = pdFAIL; + TickType_t xTimeNow; + uint32_t ulExecutionCount; + int task_res = EXAMPLE_SUCCESS; -/* The timer handles are used inside the callback function so this time are -given file scope. */ -static TimerHandle_t xAutoReloadTimer, xOneShotTimer; + /* The count of the number of times this software timer has expired is stored in the timer's ID. + * Obtain the ID, increment it, then save it as the new ID value. + * The ID is a void pointer, so is cast to a uint32_t. + */ + ulExecutionCount = (uint32_t)(uintptr)pvTimerGetTimerID(xTimer); + vPrintStringAndNumber("pvTimerGetTimerID = ", ulExecutionCount); + ulExecutionCount++; + vTimerSetTimerID(xTimer, (void *)(uintptr)ulExecutionCount); -void CreateTimerResetTasks(void) -{ - BaseType_t xTimer1Started, xTimer2Started; - - /* Create the one shot timer, storing the handle to the created timer in - xOneShotTimer. */ - xOneShotTimer = xTimerCreate("Reset OneShot", /* Text name for the timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The timer's period in ticks. */ - pdFALSE, /* Set uxAutoRealod to pdFALSE to create a one-shot timer. */ - 0, /* The timer ID is initialised to 0. */ - prvTimerCallback); /* The callback function to be used by the timer being created. */ - - /* Create the auto-reload, storing the handle to the created timer in - xAutoReloadTimer. */ - xAutoReloadTimer = xTimerCreate("Reset AutoReload", /* Text name for the timer - not used by FreeRTOS. */ - AUTO_RELOAD_TIMER_PERIOD, /* The timer's period in ticks. */ - pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload timer. */ - 0, /* The timer ID is initialised to 0. */ - prvTimerCallback); /* The callback function to be used by the timer being created. */ + /* Obtain the current tick count. */ + xTimeNow = xTaskGetTickCount(); - /* Check the timers were created. */ - if ((xOneShotTimer != NULL) && (xAutoReloadTimer != NULL)) + /* The handle of the one-shot timer was stored in xOneShotTimer when the timer was created. + * Compare the handle passed into this function with xOneShotTimer to determine if it was the one-shot or auto-reload timer that expired, + then output a string to show the time at which the callback was executed. + */ + if (xTimer == xOneShotTimer) { - /* Start the timers, using a block time of 0 (no block time). The - scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimer1Started = xTimerStart(xOneShotTimer, 0); - xTimer2Started = xTimerStart(xAutoReloadTimer, 0); + vPrintStringAndNumber("One-shot timer callback executing", xTimeNow); - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if ((xTimer1Started != pdPASS) || (xTimer2Started != pdPASS)) + /* If auto-reload timer id is not still 2, auto-reload timer stop failed. */ + ulExecutionCount = (uint32_t)(uintptr)pvTimerGetTimerID(xAutoReloadTimer); + if (ulExecutionCount != 2) { - vPrintString("CreateSoftwareTimerTasks xTimerStart failed \r\n"); + vPrintf("xTimerStop in auto reload task failed, now ulExecutionCount(should = 2) = %d \r\n", ulExecutionCount); + task_res = EXAMPLE_FAILURE; + xQueueSend(xQueue, &task_res, 0); + } + + /* Reset operation */ + vPrintString("One-shot timer reset Auto-reload timer "); + xTimerReset(xAutoReloadTimer, 0); + + xReturn = xTimerDelete(xOneShotTimer, 0); + if (xReturn != pdPASS) + { + vPrintString("DeleteTimerResetTasks xTimerDelete OneShot failed."); + } + else + { + vPrintString("Delete one-shot timer reset task."); } } else { - vPrintString("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } + /* xTimer did not equal xOneShotTimer, so it must be the auto-reload timer that expired. */ + vPrintStringAndNumber("Auto-reload timer callback executing", xTimeNow); + if (ulExecutionCount == 2) + { + /* Stop the auto-reload timer after it has executed 3 times. + * This callback function executes in the context of the RTOS daemon task so must not call any functions that might + place the daemon task into the Blocked state. + * Therefore a block time of 0 is used. + */ + xTimerStop(xTimer, 0); + vPrintString("Auto-reload timer stopped."); + } + else if (ulExecutionCount == 4) + { + xTimerStop(xTimer, 0); + vPrintString("Auto-reload timer stopped again."); + xReturn = xTimerDelete(xAutoReloadTimer, 0); + if (xReturn != pdPASS) + { + vPrintString("DeleteTimerResetTasks xTimerDelete AutoReload failed."); + task_res = EXAMPLE_FAILURE; + xQueueSend(xQueue, &task_res, 0); + } + else + { + vPrintString("Delete auto-reload timer reset tasks."); + xQueueSend(xQueue, &task_res, 0); + } + } + } } -void DeleteTimerResetTasks(void) +/*-----------------------------------------------------------*/ +/* The timer handles are used inside the callback function so this time are given file scope. */ +int CreateTimerResetTasks(void) { - BaseType_t xReturn = pdFAIL; - xReturn = xTimerDelete(xOneShotTimer, 0); - if (xReturn != pdPASS) - { - vPrintString("DeleteTimerResetTasks xTimerDelete OneShot failed.\r\n"); - } - else + BaseType_t xTimer1Started; + BaseType_t xTimer2Started; + BaseType_t xReturn = pdPASS; /* Define a return value with a default of pdPASS */ + u32 task_res = 0; + u32 task_flag = 0; + + xQueue = xQueueCreate(2, sizeof(int)); /* Create Message Queue */ + if (xQueue == NULL) { - vPrintString("DeleteTimerResetTasks xTimerDelete OneShot success.\r\n"); + vPrintf("xQueue create failed. \r\n"); + goto exit; } - xReturn = xTimerDelete(xAutoReloadTimer, 0); - if (xReturn != pdPASS) + /* Create the one shot timer, storing the handle to the created timer in xOneShotTimer. */ + xOneShotTimer = xTimerCreate("Reset OneShot", /* Text name for the timer - not used by FreeRTOS. */ + ONE_SHOT_TIMER_PERIOD, /* The timer's period in ticks. */ + pdFALSE, /* Set uxAutoRealod to pdFALSE to create a one-shot timer. */ + 0, /* The timer ID is initialised to 0. */ + prvTimerCallback); /* The callback function to be used by the timer being created. */ + + /* Create the auto-reload, storing the handle to the created timer in xAutoReloadTimer. */ + xAutoReloadTimer = xTimerCreate("Reset AutoReload", /* Text name for the timer - not used by FreeRTOS. */ + AUTO_RELOAD_TIMER_PERIOD, /* The timer's period in ticks. */ + pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload timer. */ + 0, /* The timer ID is initialised to 0. */ + prvTimerCallback); /* The callback function to be used by the timer being created. */ + + /* Check the timers were created. */ + if ((xOneShotTimer != NULL) && (xAutoReloadTimer != NULL)) { - vPrintString("DeleteTimerResetTasks xTimerDelete AutoReload failed.\r\n"); + /* Start the timers, using a block time of 0 (no block time). + * The scheduler has not been started yet so any block time specified here would be ignored anyway. + */ + xTimer1Started = xTimerStart(xOneShotTimer, 0); + xTimer2Started = xTimerStart(xAutoReloadTimer, 0); + + /* The implementation of xTimerStart() uses the timer command queue, and xTimerStart() will fail if the timer command queue gets full. + The timer service task does not get created until the scheduler is started, + so all commands sent to the command queue will stay in the queue until after the scheduler has been started. + * Check both calls to xTimerStart() passed. + */ + if ((xTimer1Started != pdPASS) || (xTimer2Started != pdPASS)) + { + vPrintString("CreateSoftwareTimerTasks xTimerStart failed."); + goto exit; + } } else { - vPrintString("DeleteTimerResetTasks xTimerDelete AutoReload success.\r\n"); + vPrintString("CreateSoftwareTimerTasks xTimerCreate failed."); + goto exit; } -} - -/*-----------------------------------------------------------*/ - -static void prvTimerCallback(TimerHandle_t xTimer) -{ - TickType_t xTimeNow; - uint32_t ulExecutionCount; - /* The count of the number of times this software timer has expired is - stored in the timer's ID. Obtain the ID, increment it, then save it as the - new ID value. The ID is a void pointer, so is cast to a uint32_t. */ - ulExecutionCount = (uint32_t)(uintptr) pvTimerGetTimerID(xTimer); - vPrintStringAndNumber("pvTimerGetTimerID = ", ulExecutionCount); - ulExecutionCount++; - vTimerSetTimerID(xTimer, (void *)(uintptr)ulExecutionCount); + xReturn = xQueueReceive(xQueue, &task_res, EXAMPLE_TIMEOUT); + if (xReturn == pdFAIL) + { + vPrintString("xQueue receive timeout."); + goto exit; + } - /* Obtain the current tick count. */ - xTimeNow = xTaskGetTickCount(); +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } - /* The handle of the one-shot timer was stored in xOneShotTimer when the - timer was created. Compare the handle passed into this function with - xOneShotTimer to determine if it was the one-shot or auto-reload timer that - expired, then output a string to show the time at which the callback was - executed. */ - if (xTimer == xOneShotTimer) + if (task_res != EXAMPLE_SUCCESS) { - vPrintStringAndNumber("One-shot timer callback executing", xTimeNow); - vPrintString("One-shot timer reset Auto-reload timer "); - xTimerReset(xAutoReloadTimer, 0); + vPrintf("%s@%d: Software timer set timer id and reset example [failure], task_res = %d \r\n", __func__, __LINE__, task_res); + return task_res; } else { - /* xTimer did not equal xOneShotTimer, so it must be the auto-reload - timer that expired. */ - vPrintStringAndNumber("Auto-reload timer callback executing", xTimeNow); - - if (ulExecutionCount == 3) - { - /* Stop the auto-reload timer after it has executed 5 times. This - callback function executes in the context of the RTOS daemon task so - must not call any functions that might place the daemon task into - the Blocked state. Therefore a block time of 0 is used. */ - xTimerStop(xTimer, 0); - vPrintString("Auto-reload timer stopped!!! "); - } + vPrintf("%s@%d: Software timer set timer id and reset example [success]. \r\n", __func__, __LINE__); + return task_res; } -} -/*-----------------------------------------------------------*/ - +} \ No newline at end of file diff --git a/example/freertos_feature/task/README.md b/example/freertos_feature/task/README.md index 35384653687b9e869421b61bc25f9fcd2561c141..81c22b04a29df16e7a588fc9ea913412d8349678 100644 --- a/example/freertos_feature/task/README.md +++ b/example/freertos_feature/task/README.md @@ -9,7 +9,7 @@ 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 diff --git a/example/freertos_feature/task_notify/README.md b/example/freertos_feature/task_notify/README.md index cb223a7031c44bea41e36d4b071aadbb4a1b119d..959b0250be56f4aad76acb483d4de8cbf52ddaad 100644 --- a/example/freertos_feature/task_notify/README.md +++ b/example/freertos_feature/task_notify/README.md @@ -13,7 +13,7 @@ FreeRTOS 从 V8.2.0 版本开始提供任务通知这个功能,每个任务都 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -82,9 +82,13 @@ bootelf -p 0x90100000 - 系统进入后,输入```notify```查看指令说明 - 输入```notify true_cre```,启动ulTaskNotifyTake pdTRUE测试 -- 输入```notify true_del```,删除ulTaskNotifyTake pdTRUE测试 + +![true_cre](./figs/true_cre.png) + - 输入```notify false_cre```,启动ulTaskNotifyTake pdFALSE测试 -- 输入```notify false_del```,删除ulTaskNotifyTake pdFALSE测试 + +![false_cre](./figs/false_cre.png) + - 测试任务能够能正常创建和删除,输入```ps```查看任务状态正常,即测试正常 ![](./pic/task_notify.png) diff --git a/example/freertos_feature/task_notify/figs/false_cre.png b/example/freertos_feature/task_notify/figs/false_cre.png new file mode 100644 index 0000000000000000000000000000000000000000..b12ee1cc4502f79473f63d18f1063a87f524b182 Binary files /dev/null and b/example/freertos_feature/task_notify/figs/false_cre.png differ diff --git a/example/freertos_feature/task_notify/figs/true_cre.png b/example/freertos_feature/task_notify/figs/true_cre.png new file mode 100644 index 0000000000000000000000000000000000000000..31b76655c55169fca325bf1c28020c9745dfc95a Binary files /dev/null and b/example/freertos_feature/task_notify/figs/true_cre.png differ diff --git a/example/freertos_feature/task_notify/inc/feature_task_notify.h b/example/freertos_feature/task_notify/inc/feature_task_notify.h index 9e3496932e4521ecd5b6851be8b63ff3fe86b678..650ea5ec2acaf40f2aee122659006063537a75f7 100644 --- a/example/freertos_feature/task_notify/inc/feature_task_notify.h +++ b/example/freertos_feature/task_notify/inc/feature_task_notify.h @@ -25,19 +25,17 @@ #ifndef FEATURE_EVENTGROUP_H #define FEATURE_EVENTGROUP_H - +#include "FreeRTOS.h" #ifdef __cplusplus extern "C" { #endif /* task notify use true */ -void CreateNotifyTakeTrueTasks(void); -void DeleteNotifyTakeTrueTasks(void); +BaseType_t CreateNotifyTakeTrueTasks(void); /* task notify use false */ -void CreateNotifyTakeFalseTasks(void); -void DeleteNotifyTakeFalseTasks(void); +BaseType_t CreateNotifyTakeFalseTasks(void); #ifdef __cplusplus } diff --git a/example/freertos_feature/task_notify/main.c b/example/freertos_feature/task_notify/main.c index b20740a55cbb4e3e24a1b368d44d7d1229b28f7d..f4b3f2811488c6531b73f2d702bdc2b5cd08abc7 100644 --- a/example/freertos_feature/task_notify/main.c +++ b/example/freertos_feature/task_notify/main.c @@ -22,24 +22,52 @@ * 1.0 wangxiaodong 2022/08/09 first commit */ +#include +#include "FreeRTOS.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include +#else +#include "task.h" +#include "feature_task_notify.h" +void NotifyExampleTaskEntry(void) +{ + CreateNotifyTakeTrueTasks(); + CreateNotifyTakeFalseTasks(); + + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif int main(void) { BaseType_t ret; +#ifdef CONFIG_USE_LETTER_SHELL ret = LSUserShellTask() ; if (ret != pdPASS) { goto FAIL_EXIT; } +#else + + taskENTER_CRITICAL(); /*进入临界区*/ + ret = xTaskCreate((TaskFunction_t)NotifyExampleTaskEntry, /* 任务入口函数 */ + (const char *)"NotifyExampleTaskEntry",/* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)8, /* 任务的优先级 */ + NULL); + taskEXIT_CRITICAL(); /*退出临界区*/ + +#endif vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("failed 0x%x. \r\n", ret); + printf("Failed 0x%x. \r\n", ret); return 0; } diff --git a/example/freertos_feature/task_notify/pic/task_notify.png b/example/freertos_feature/task_notify/pic/task_notify.png deleted file mode 100644 index 9d1cde1a109927e3a5953d1f3116bcc0c0ac05d9..0000000000000000000000000000000000000000 Binary files a/example/freertos_feature/task_notify/pic/task_notify.png and /dev/null differ diff --git a/example/freertos_feature/task_notify/src/notify_take_false.c b/example/freertos_feature/task_notify/src/notify_take_false.c index 1c5dd259cc0571af7d423c7ffa8139aa09b829dc..f3de56cf5ca2f694e44d526bb49aac5d30a26418 100644 --- a/example/freertos_feature/task_notify/src/notify_take_false.c +++ b/example/freertos_feature/task_notify/src/notify_take_false.c @@ -12,6 +12,11 @@ that have occurred, and the number of events that have been processed. #include "semphr.h" #include "finterrupt.h" #include "fcpu_info.h" +#include "event_groups.h" + +static EventGroupHandle_t xEventGroup; +#define TEST_COMPLETE_FLAG ( 1UL << 0UL ) /* Event bit 0, which is set by a task. */ +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) #define TASK_STACK_SIZE 1024 @@ -40,7 +45,7 @@ that the task will be synchronized with. */ static void vSetupSoftwareInterrupt(void); /* The rate at which the periodic task generates software interrupts. */ -static const TickType_t xInterruptFrequency = pdMS_TO_TICKS(5000UL); +static const TickType_t xInterruptFrequency = pdMS_TO_TICKS(500UL); /* Stores the handle of the task to which interrupt processing is deferred. */ static xTaskHandle xtask1_handle = NULL; @@ -50,45 +55,6 @@ static u32 cpu_id = 0; /*-----------------------------------------------------------*/ -void CreateNotifyTakeFalseTasks(void) -{ - /* Install the handler for the software interrupt. The syntax necessary - to do this is dependent on the FreeRTOS port being used. The syntax - shown here can only be used with the FreeRTOS Windows port, where such - interrupts are only simulated. */ - vSetupSoftwareInterrupt(); - - /* Create the 'handler' task, which is the task to which interrupt - processing is deferred, and so is the task that will be synchronized - with the interrupt. The handler task is created with a high priority to - ensure it runs immediately after the interrupt exits. In this case a - priority of 3 is chosen. The handle of the task is saved for use by the - ISR. */ - xTaskCreate(vHandlerTask, "Notify False Handler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); - - /* Create the task that will periodically generate a software interrupt. - This is created with a priority below the handler task to ensure it will - get preempted each time the handler task exits the Blocked state. */ - xTaskCreate(vPeriodicTask, "Notify False Periodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); - -} - -void DeleteNotifyTakeFalseTasks(void) -{ - if (xtask1_handle) - { - vTaskDelete(xtask1_handle); - vPrintString("Task notify false Handler deletion"); - } - - if (xtask2_handle) - { - vTaskDelete(xtask2_handle); - vPrintString("Task notify false Periodic deletion"); - } -} -/*-----------------------------------------------------------*/ - static void vHandlerTask(void *pvParameters) { /* xMaxExpectedBlockTime is set to be a little longer than the maximum expected @@ -111,12 +77,11 @@ static void vHandlerTask(void *pvParameters) vPrintString("Task Notify False Handler task - Processing event.\r\n"); vPrintStringAndNumber("Task Notify False ulNotificationValue= ", ulNotificationValue); } - else + if (ulNotificationValue == 1) { - /* If this part of the function is reached then an interrupt did not - arrive within the expected time, and (in a real application) it may - be necessary to perform some error recovery operations. */ + xEventGroupSetBits(xEventGroup, TEST_COMPLETE_FLAG); } + } } /*-----------------------------------------------------------*/ @@ -196,11 +161,75 @@ static void vTriggerInterrupt(void) InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); } +/*-----------------------------------------------------------*/ +void DeleteNotifyTakeFalseTasks(void) +{ + if (xtask1_handle) + { + vTaskDelete(xtask1_handle); + vPrintString("Task notify True Handler deletion \r\n"); + } + if (xtask2_handle) + { + vTaskDelete(xtask2_handle); + vPrintString("Task notify True vPeriodicTask deletion \r\n"); + } +} + +BaseType_t CreateNotifyTakeFalseTasks(void) +{ + BaseType_t ret; + EventBits_t xEventGroupValue = 0; + const EventBits_t xBitsToWaitFor = TEST_COMPLETE_FLAG; + xEventGroup = xEventGroupCreate(); + /* Install the handler for the software interrupt. The syntax necessary + to do this is dependent on the FreeRTOS port being used. The syntax + shown here can only be used with the FreeRTOS Windows port, where such + interrupts are only simulated. */ + vSetupSoftwareInterrupt(); + /* Create the 'handler' task, which is the task to which interrupt + processing is deferred, and so is the task that will be synchronized + with the interrupt. The handler task is created with a high priority to + ensure it runs immediately after the interrupt exits. In this case a + priority of 3 is chosen. The handle of the task is saved for use by the + ISR. */ + ret = xTaskCreate(vHandlerTask, "Notify False Handler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); + if (ret != pdPASS) + { + xtask1_handle = NULL; + vPrintStringAndNumber("vHandlerTask creation failed: ", ret); + goto exit; + } + /* Create the task that will periodically generate a software interrupt. + This is created with a priority below the handler task to ensure it will + get preempted each time the handler task exits the Blocked state. */ + ret = xTaskCreate(vPeriodicTask, "Notify False Periodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); + if (ret != pdPASS) + { + xtask2_handle = NULL; + vPrintStringAndNumber("vPeriodicTask creation failed: ", ret); + goto exit; + } + /* Block to wait for event bits to become set within the event group. */ + xEventGroupValue = xEventGroupWaitBits(xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, TIMER_OUT); +exit: + DeleteNotifyTakeFalseTasks(); + if (xEventGroupValue != xBitsToWaitFor) + { + vPrintf("%s@%d: Notify take false example [failure].\r\n", __func__, __LINE__); + return pdFAIL; + } + else + { + vPrintf("%s@%d: Notify take false example [success].\r\n", __func__, __LINE__); + return pdTRUE; + } +} diff --git a/example/freertos_feature/task_notify/src/notify_take_true.c b/example/freertos_feature/task_notify/src/notify_take_true.c index dbd5c43fd1f42d2eafabe7f728066a9d1bac9840..cb3a3481c74d5932f810227c98015ca50118a65a 100644 --- a/example/freertos_feature/task_notify/src/notify_take_true.c +++ b/example/freertos_feature/task_notify/src/notify_take_true.c @@ -5,11 +5,17 @@ service routine—effectively synchronizing the task with the interrupt. the ulTaskNotifyTake() xClearOnExit parameter was set to pdTRUE. */ +#include #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include "finterrupt.h" #include "fcpu_info.h" +#include "event_groups.h" + +static EventGroupHandle_t xEventGroup; +#define TEST_COMPLETE_FLAG ( 1UL << 0UL ) /* Event bit 0, which is set by a task. */ +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) static xTaskHandle xtask1_handle = NULL; static xTaskHandle xtask2_handle = NULL; @@ -29,6 +35,8 @@ numeric values represent low priority values, which can be confusing as it is counter intuitive. */ #define INTERRUPT_PRIORITY IRQ_PRIORITY_VALUE_12 +#define TOTAL_NOTIFY_TEST_TIMES 3 + /* Macro to force an interrupt. */ static void vTriggerInterrupt(void); @@ -41,49 +49,13 @@ that sets an event bit in the event group. */ static void vSetupSoftwareInterrupt(void); /* The rate at which the periodic task generates software interrupts. */ -static const TickType_t xInterruptFrequency = pdMS_TO_TICKS(5000UL); +static const TickType_t xInterruptFrequency = pdMS_TO_TICKS(1000UL); static u32 cpu_id = 0; -/*-----------------------------------------------------------*/ - -void CreateNotifyTakeTrueTasks(void) -{ - /* Install the handler for the software interrupt. The syntax necessary - to do this is dependent on the FreeRTOS port being used. The syntax - shown here can only be used with the FreeRTOS Windows port, where such - interrupts are only simulated. */ - vSetupSoftwareInterrupt(); - - /* Create the 'handler' task, which is the task to which interrupt - processing is deferred, and so is the task that will be synchronized - with the interrupt. The handler task is created with a high priority to - ensure it runs immediately after the interrupt exits. In this case a - priority of 3 is chosen. The handle of the task is saved for use by the - ISR. */ - xTaskCreate(vHandlerTask, "Notify True Handler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); - - /* Create the task that will periodically generate a software interrupt. - This is created with a priority below the handler task to ensure it will - get preempted each time the handler task exits the Blocked state. */ - xTaskCreate(vPeriodicTask, "Notify True Periodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); +static u32 NotifyTakeTimes = 0; +static u32 NotifySendTimes = 0; -} - -void DeleteNotifyTakeTrueTasks(void) -{ - if (xtask1_handle) - { - vTaskDelete(xtask1_handle); - vPrintString("Task notify True Handler deletion \r\n"); - } - - if (xtask2_handle) - { - vTaskDelete(xtask2_handle); - vPrintString("Task notify True Periodic deletion \r\n"); - } -} /*-----------------------------------------------------------*/ static void vHandlerTask(void *pvParameters) @@ -106,15 +78,14 @@ static void vHandlerTask(void *pvParameters) print out a message for each event). */ while (ulEventsToProcess > 0) { - vPrintString("Task notify True Handler task - Processing event."); + printf("ulEventsToProcess = %d, NotifyTakeTimes = %d\n", ulEventsToProcess, NotifyTakeTimes); ulEventsToProcess--; } + NotifyTakeTimes++; } - else + if(NotifyTakeTimes == TOTAL_NOTIFY_TEST_TIMES) { - /* If this part of the function is reached then an interrupt did not - arrive within the expected time, and (in a real application) it may - be necessary to perform some error recovery operations. */ + xEventGroupSetBits(xEventGroup, TEST_COMPLETE_FLAG); } } } @@ -128,17 +99,12 @@ static void ulExampleInterruptHandler(s32 vector, void *param) it will get set to pdTRUE inside the interrupt safe API function if a context switch is required. */ xHigherPriorityTaskWoken = pdFALSE; - - /* Send a notification directly to the handler task. */ - vTaskNotifyGiveFromISR(/* The handle of the task to which the notification - is being sent. The handle was saved when the task - was created. */ - xtask1_handle, - - /* xHigherPriorityTaskWoken is used in the usual - way. */ - &xHigherPriorityTaskWoken); - + if (NotifySendTimes < TOTAL_NOTIFY_TEST_TIMES) + { + /* Send a notification directly to the handler task. */ + vTaskNotifyGiveFromISR(xtask1_handle, &xHigherPriorityTaskWoken); + NotifySendTimes++; + } /* Pass the xHigherPriorityTaskWoken value into portYIELD_FROM_ISR(). If xHigherPriorityTaskWoken was set to pdTRUE inside vTaskNotifyGiveFromISR() then calling portYIELD_FROM_ISR() will request a context switch. If @@ -196,6 +162,73 @@ static void vTriggerInterrupt(void) InterruptCoreInterSend(INTERRUPT_ID, (1 << cpu_id)); } +void DeleteNotifyTakeTrueTasks(void) +{ + if (xtask1_handle) + { + vTaskDelete(xtask1_handle); + vPrintString("Task notify True Handler deletion \r\n"); + } + if (xtask2_handle) + { + vTaskDelete(xtask2_handle); + vPrintString("Task notify True vPeriodicTask deletion \r\n"); + } +} + +BaseType_t CreateNotifyTakeTrueTasks(void) +{ + BaseType_t ret; + EventBits_t xEventGroupValue = 0; + const EventBits_t xBitsToWaitFor = TEST_COMPLETE_FLAG; + + xEventGroup = xEventGroupCreate(); + /* Install the handler for the software interrupt. The syntax necessary + to do this is dependent on the FreeRTOS port being used. The syntax + shown here can only be used with the FreeRTOS Windows port, where such + interrupts are only simulated. */ + vSetupSoftwareInterrupt(); + + /* Create the 'handler' task, which is the task to which interrupt + processing is deferred, and so is the task that will be synchronized + with the interrupt. The handler task is created with a high priority to + ensure it runs immediately after the interrupt exits. In this case a + priority of 3 is chosen. The handle of the task is saved for use by the + ISR. */ + ret = xTaskCreate(vHandlerTask, "Notify True Handler", TASK_STACK_SIZE, NULL, 3, &xtask1_handle); + if (ret != pdPASS) + { + xtask1_handle = NULL; + vPrintStringAndNumber("vHandlerTask creation failed: ", ret); + goto exit; + } + /* Create the task that will periodically generate a software interrupt. + This is created with a priority below the handler task to ensure it will + get preempted each time the handler task exits the Blocked state. */ + ret = xTaskCreate(vPeriodicTask, "Notify True Periodic", TASK_STACK_SIZE, NULL, 1, &xtask2_handle); + if (ret != pdPASS) + { + xtask2_handle = NULL; + vPrintStringAndNumber("vPeriodicTask creation failed: ", ret); + goto exit; + } + /* Block to wait for event bits to become set within the event group. */ + xEventGroupValue = xEventGroupWaitBits(xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, TIMER_OUT); + +exit: + DeleteNotifyTakeTrueTasks(); + if (xEventGroupValue != xBitsToWaitFor) + { + vPrintf("%s@%d: Notify take true example [failure].\r\n", __func__, __LINE__); + return pdFAIL; + } + else + { + vPrintf("%s@%d: Notify take true example [success].\r\n", __func__, __LINE__); + return pdTRUE; + } +} + diff --git a/example/freertos_feature/task_notify/src/task_notify_cmd.c b/example/freertos_feature/task_notify/src/task_notify_cmd.c index 820e8bafb35a55c64b938a7042a1361f678af2fa..5304c2bc60ff123c9534dd0fd74de7c1fa517904 100644 --- a/example/freertos_feature/task_notify/src/task_notify_cmd.c +++ b/example/freertos_feature/task_notify/src/task_notify_cmd.c @@ -21,36 +21,25 @@ * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2022/08/09 first commit */ -#include "shell.h" #include #include #include "feature_task_notify.h" - -typedef enum -{ - NOTIFY_TAKE_TRUE_TASK_INDEX = 0, - NOTIFY_TAKE_FALSE_TASK_INDEX = 1, - NOTIFY_FEATURE_LENGTH -} FreeRtosTaskNotifyFeatureSelect; +#include "sdkconfig.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "../src/shell.h" static void TaskNotifyCmdUsage(void) { printf("Usage:\r\n"); printf(" notify true_cre \r\n"); printf(" -- Create task notify test now, use notify take true.\r\n"); - printf(" notify true_del \r\n"); - printf(" -- Del notify take true tasks now.\r\n"); printf(" notify false_cre \r\n"); printf(" -- Create task notify test now, use notify take false.\r\n"); - printf(" notify false_del \r\n"); - printf(" -- Del notify take false tasks now.\r\n"); } int TaskNotifyCmd(int argc, char *argv[]) { - static int create_flg[NOTIFY_FEATURE_LENGTH] = {0}; /* 1 is tasks has been created*/ - if (argc < 2) { TaskNotifyCmdUsage(); @@ -59,51 +48,11 @@ int TaskNotifyCmd(int argc, char *argv[]) if (!strcmp(argv[1], "true_cre")) { - if (create_flg[NOTIFY_TAKE_TRUE_TASK_INDEX] == 0) - { - CreateNotifyTakeTrueTasks(); - create_flg[NOTIFY_TAKE_TRUE_TASK_INDEX] = 1; - } - else - { - printf("Please use true_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "true_del")) - { - if (create_flg[NOTIFY_TAKE_TRUE_TASK_INDEX] == 1) - { - DeleteNotifyTakeTrueTasks(); - create_flg[NOTIFY_TAKE_TRUE_TASK_INDEX] = 0; - } - else - { - printf("Please use true_cre cmd first. \r\n"); - } + CreateNotifyTakeTrueTasks(); } else if (!strcmp(argv[1], "false_cre")) { - if (create_flg[NOTIFY_TAKE_FALSE_TASK_INDEX] == 0) - { - CreateNotifyTakeFalseTasks(); - create_flg[NOTIFY_TAKE_FALSE_TASK_INDEX] = 1; - } - else - { - printf("Please use false_del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "false_del")) - { - if (create_flg[NOTIFY_TAKE_FALSE_TASK_INDEX] == 1) - { - DeleteNotifyTakeFalseTasks(); - create_flg[NOTIFY_TAKE_FALSE_TASK_INDEX] = 0; - } - else - { - printf("Please use false_cre cmd first. \r\n"); - } + CreateNotifyTakeFalseTasks(); } else { @@ -112,7 +61,6 @@ int TaskNotifyCmd(int argc, char *argv[]) } return 0; } - SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), notify, TaskNotifyCmd, task notify test); - +#endif diff --git a/example/network/lwip_iperf/README.md b/example/network/lwip_iperf/README.md index 4c6a770ddd0473246cb6c243885adda76692d398..93834fc63b6d07244437aac49a851e14cab065b7 100644 --- a/example/network/lwip_iperf/README.md +++ b/example/network/lwip_iperf/README.md @@ -119,18 +119,34 @@ lwip iperfc ``` ![iperf_client_example_result](./fig/iperf_client_example.png) +![iperf_client_test_result](./fig/iperf_client_test.png) #### 2.4.2 网卡iperf server测试例程 (lwip_iperf_server_example.c) ``` lwip iperfs ``` ![iperf_server_example_result](./fig/iperf_server_example.png) - +![iperf_server_test_result](./fig/iperf_server_test.png) ## 3. 如何解决问题 >主要记录使用例程中可能会遇到的问题,给出相应的解决方案
+- Q: 如何静态配置开发板的ip地址? +- A: ipv4地址在board_mac_config静态变量中修改如下成员变量即可: + +``` + .ipaddr="192.168.4.10", + .gw="192.168.4.1", + .netmask="255.255.255.0", +``` + +- A: ipv6地址在board_mac_config静态变量中修改如下成员变量即可: + +``` + .mac_address={0x98, 0x0e, 0x24, 0x00, 0x11, 0x1}, +``` + ## 4. 修改历史记录 >记录例程的重大修改记录,标明修改发生的版本号
diff --git a/example/network/lwip_iperf/configs/e2000d_aarch32_demo_lwip_iperf.config b/example/network/lwip_iperf/configs/e2000d_aarch32_demo_lwip_iperf.config index 42cb2efb3d56d8270a83eb0676038548908306fc..18e076087440ad6e1d17bbf03e5e96b99288239b 100644 --- a/example/network/lwip_iperf/configs/e2000d_aarch32_demo_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/e2000d_aarch32_demo_lwip_iperf.config @@ -177,8 +177,9 @@ CONFIG_OUTPUT_BINARY=y # Optimization options # # CONFIG_DEBUG_NOOPT is not set -# CONFIG_DEBUG_CUSTOMOPT is not set -CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_CUSTOMOPT=y +# CONFIG_DEBUG_FULLOPT is not set +CONFIG_DEBUG_OPTLEVEL="-O2" CONFIG_DEBUG_OPT_UNUSED_SECTIONS=y CONFIG_DEBUG_LINK_MAP=y # CONFIG_CCACHE is not set diff --git a/example/network/lwip_iperf/configs/e2000d_aarch64_demo_lwip_iperf.config b/example/network/lwip_iperf/configs/e2000d_aarch64_demo_lwip_iperf.config index 7f642942b1849c1e9c0d51117755a7ac3f70583d..2784a74673fe081c1996aeb78e56b68308303fd7 100644 --- a/example/network/lwip_iperf/configs/e2000d_aarch64_demo_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/e2000d_aarch64_demo_lwip_iperf.config @@ -171,8 +171,9 @@ CONFIG_OUTPUT_BINARY=y # Optimization options # # CONFIG_DEBUG_NOOPT is not set -# CONFIG_DEBUG_CUSTOMOPT is not set -CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_CUSTOMOPT=y +# CONFIG_DEBUG_FULLOPT is not set +CONFIG_DEBUG_OPTLEVEL="-O2" CONFIG_DEBUG_OPT_UNUSED_SECTIONS=y CONFIG_DEBUG_LINK_MAP=y # CONFIG_CCACHE is not set diff --git a/example/network/lwip_iperf/configs/e2000q_aarch32_demo_lwip_iperf.config b/example/network/lwip_iperf/configs/e2000q_aarch32_demo_lwip_iperf.config index 6bf772a865234bb14aceec58ac45f7fc49ae3dc6..44ec4acbc0bddeb0ac7bb764ce5b0ca4f5563c74 100644 --- a/example/network/lwip_iperf/configs/e2000q_aarch32_demo_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/e2000q_aarch32_demo_lwip_iperf.config @@ -176,8 +176,9 @@ CONFIG_OUTPUT_BINARY=y # Optimization options # # CONFIG_DEBUG_NOOPT is not set -# CONFIG_DEBUG_CUSTOMOPT is not set -CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_CUSTOMOPT=y +# CONFIG_DEBUG_FULLOPT is not set +CONFIG_DEBUG_OPTLEVEL="-O2" CONFIG_DEBUG_OPT_UNUSED_SECTIONS=y CONFIG_DEBUG_LINK_MAP=y # CONFIG_CCACHE is not set diff --git a/example/network/lwip_iperf/configs/e2000q_aarch64_demo_lwip_iperf.config b/example/network/lwip_iperf/configs/e2000q_aarch64_demo_lwip_iperf.config index 2489ed5ff41eec619d815c1554af396579cf332a..856f57acd0a72200d34d88b3be961b39f4f1870c 100644 --- a/example/network/lwip_iperf/configs/e2000q_aarch64_demo_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/e2000q_aarch64_demo_lwip_iperf.config @@ -170,8 +170,9 @@ CONFIG_OUTPUT_BINARY=y # Optimization options # # CONFIG_DEBUG_NOOPT is not set -# CONFIG_DEBUG_CUSTOMOPT is not set -CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_CUSTOMOPT=y +# CONFIG_DEBUG_FULLOPT is not set +CONFIG_DEBUG_OPTLEVEL="-O2" CONFIG_DEBUG_OPT_UNUSED_SECTIONS=y CONFIG_DEBUG_LINK_MAP=y # CONFIG_CCACHE is not set diff --git a/example/network/lwip_iperf/configs/phytiumpi_aarch32_firefly_lwip_iperf.config b/example/network/lwip_iperf/configs/phytiumpi_aarch32_firefly_lwip_iperf.config index e069e248d05ffe10eead7a5c67cac83fce365288..7ddc51241c927243c0aa4dbf3faa1932bc780a69 100644 --- a/example/network/lwip_iperf/configs/phytiumpi_aarch32_firefly_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/phytiumpi_aarch32_firefly_lwip_iperf.config @@ -175,8 +175,9 @@ CONFIG_OUTPUT_BINARY=y # Optimization options # # CONFIG_DEBUG_NOOPT is not set -# CONFIG_DEBUG_CUSTOMOPT is not set -CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_CUSTOMOPT=y +# CONFIG_DEBUG_FULLOPT is not set +CONFIG_DEBUG_OPTLEVEL="-O2" CONFIG_DEBUG_OPT_UNUSED_SECTIONS=y CONFIG_DEBUG_LINK_MAP=y # CONFIG_CCACHE is not set diff --git a/example/network/lwip_iperf/configs/phytiumpi_aarch64_firefly_lwip_iperf.config b/example/network/lwip_iperf/configs/phytiumpi_aarch64_firefly_lwip_iperf.config index 2778ea057bdced5ead45040ec7fc92ed6deaf83f..35e69fe5238afe71114974fd336a322684ea98aa 100644 --- a/example/network/lwip_iperf/configs/phytiumpi_aarch64_firefly_lwip_iperf.config +++ b/example/network/lwip_iperf/configs/phytiumpi_aarch64_firefly_lwip_iperf.config @@ -169,8 +169,9 @@ CONFIG_OUTPUT_BINARY=y # Optimization options # # CONFIG_DEBUG_NOOPT is not set -# CONFIG_DEBUG_CUSTOMOPT is not set -CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_CUSTOMOPT=y +# CONFIG_DEBUG_FULLOPT is not set +CONFIG_DEBUG_OPTLEVEL="-O2" CONFIG_DEBUG_OPT_UNUSED_SECTIONS=y CONFIG_DEBUG_LINK_MAP=y # CONFIG_CCACHE is not set diff --git a/example/network/lwip_iperf/fig/iperf_client_example.png b/example/network/lwip_iperf/fig/iperf_client_example.png index c1183ac8923d8a446a21179d9890456cbfc2b8f9..68f6f04a334d2d441f09ac777d80c23691e94a28 100644 Binary files a/example/network/lwip_iperf/fig/iperf_client_example.png and b/example/network/lwip_iperf/fig/iperf_client_example.png differ diff --git a/example/network/lwip_iperf/fig/iperf_client_test.png b/example/network/lwip_iperf/fig/iperf_client_test.png new file mode 100644 index 0000000000000000000000000000000000000000..267e4f60aee3cf0c63e5a4d2b59fa3b5e7578a90 Binary files /dev/null and b/example/network/lwip_iperf/fig/iperf_client_test.png differ diff --git a/example/network/lwip_iperf/fig/iperf_server_example.png b/example/network/lwip_iperf/fig/iperf_server_example.png index f5fcade1ad054c3d6a3c2323defe67a5df9440c1..e40d2191aa4f9b60a534157065851eeefcc9d712 100644 Binary files a/example/network/lwip_iperf/fig/iperf_server_example.png and b/example/network/lwip_iperf/fig/iperf_server_example.png differ diff --git a/example/network/lwip_iperf/fig/iperf_server_test.png b/example/network/lwip_iperf/fig/iperf_server_test.png new file mode 100644 index 0000000000000000000000000000000000000000..210671a83d1beec0aaad2a3865d146ec7caa2c4d Binary files /dev/null and b/example/network/lwip_iperf/fig/iperf_server_test.png differ diff --git a/example/network/lwip_iperf/inc/lwip_iperf_client_example.h b/example/network/lwip_iperf/inc/lwip_iperf_client_example.h index b918db5def9ea53a0301eb89d426ea5d3a66938f..4231418da84b7b329529d33bf721320a13a05197 100644 --- a/example/network/lwip_iperf/inc/lwip_iperf_client_example.h +++ b/example/network/lwip_iperf/inc/lwip_iperf_client_example.h @@ -13,13 +13,14 @@ * * FilePath: lwip_iperf_client_example.h * Created Date: 2023-10-18 14:37:22 - * Last Modified: 2023-10-24 14:23:07 + * Last Modified: 2024-04-28 10:24:27 * Description: This file is for lwip iperf client example function definition. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/10/18 first release + * 2.0 liuzhihong 2024/04/28 add no letter shell mode, adapt to auto-test system */ #ifndef LWIP_IPERF_CLIENT_EXAMPLE_H #define LWIP_IPERF_CLIENT_EXAMPLE_H @@ -42,7 +43,8 @@ extern "C" /************************** Function Prototypes ******************************/ /* entry function for lwip iperf client example */ -int LwipIperfClientCreate(void); + +int FFreeRTOSLwipIperfClientTaskCreate(void); void LwipIperfClientDeinit(void); #ifdef __cplusplus diff --git a/example/network/lwip_iperf/inc/lwip_iperf_server_example.h b/example/network/lwip_iperf/inc/lwip_iperf_server_example.h index 90bf21ce97e8e157831f6ebd31046ce41bbc18a2..565a4e74de3d2a80216c6c3e232a6af622dc1698 100644 --- a/example/network/lwip_iperf/inc/lwip_iperf_server_example.h +++ b/example/network/lwip_iperf/inc/lwip_iperf_server_example.h @@ -20,6 +20,7 @@ * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/10/16 first release + * 2.0 liuzhihong 2024/04/28 add no letter shell mode, adapt to auto-test system */ #ifndef LWIP_IPERF_SERVER_EXAMPLE_H @@ -43,7 +44,7 @@ extern "C" /************************** Function Prototypes ******************************/ /* entry function for lwip iperf server example */ -int LwipIperfServerCreate(void); +int FFreeRTOSLwipIperfServerTaskCreate(void); void LwipIperfServerDeinit(void); #ifdef __cplusplus diff --git a/example/network/lwip_iperf/main.c b/example/network/lwip_iperf/main.c index 88e4a8078b3ebb578e133ddf1b412483e715b381..dc881a5ff75262684a331155d4c1fd3c316f5b18 100644 --- a/example/network/lwip_iperf/main.c +++ b/example/network/lwip_iperf/main.c @@ -13,37 +13,71 @@ * * FilePath: main.c * Created Date: 2023-12-29 14:06:16 - * Last Modified: 2024-03-28 11:18:40 + * Last Modified: 2024-04-29 14:34:19 * Description: This file is for lwip iperf example main functions. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2024/3/28 first release + * 2.0 liuzhihong 2024/4/28 add no letter shell mode, adapt to auto-test system */ #include #include "FreeRTOS.h" #include "task.h" -#include "shell_port.h" #include "lwip/tcpip.h" -int main() +#include "sdkconfig.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "shell_port.h" +#else +#include "lwip_iperf_client_example.h" +#include "lwip_iperf_server_example.h" + +#define LWIP_IPERF_EXAMPLE_TASK_PRIORITY 2 + +void LwipIperfExampleTaskEntry() +{ + /* example functions */ + FFreeRTOSLwipIperfClientTaskCreate(); + LwipIperfClientDeinit(); + + FFreeRTOSLwipIperfServerTaskCreate(); + LwipIperfServerDeinit(); + + /* end flag */ + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif + +int main(void) { - BaseType_t ret = pdPASS; + BaseType_t ret = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ +#ifdef CONFIG_USE_LETTER_SHELL ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)LwipIperfExampleTaskEntry, /* 任务入口函数 */ + (const char *)"LwipIperfExampleTaskEntry", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)LWIP_IPERF_EXAMPLE_TASK_PRIORITY, /* 任务优先级 */ + NULL); /* 任务句柄 */ +#endif if (ret != pdPASS) { goto FAIL_EXIT; } - + tcpip_init(NULL, NULL); - vTaskStartScheduler(); /* 启动任务,开启调度 */ + /* 启动任务,开启调度 */ + vTaskStartScheduler(); while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("Failed 0x%x.\r\n", ret); - - return 0; + printf("Failed,the ret value is 0x%x. \r\n", ret); + return -2; } \ No newline at end of file diff --git a/example/network/lwip_iperf/sdkconfig b/example/network/lwip_iperf/sdkconfig index 2778ea057bdced5ead45040ec7fc92ed6deaf83f..35e69fe5238afe71114974fd336a322684ea98aa 100644 --- a/example/network/lwip_iperf/sdkconfig +++ b/example/network/lwip_iperf/sdkconfig @@ -169,8 +169,9 @@ CONFIG_OUTPUT_BINARY=y # Optimization options # # CONFIG_DEBUG_NOOPT is not set -# CONFIG_DEBUG_CUSTOMOPT is not set -CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_CUSTOMOPT=y +# CONFIG_DEBUG_FULLOPT is not set +CONFIG_DEBUG_OPTLEVEL="-O2" CONFIG_DEBUG_OPT_UNUSED_SECTIONS=y CONFIG_DEBUG_LINK_MAP=y # CONFIG_CCACHE is not set diff --git a/example/network/lwip_iperf/sdkconfig.h b/example/network/lwip_iperf/sdkconfig.h index e873219a4488e63bb98e0c83dc879e78b7ff614e..43605663e355fb15aa74cfa1d177067e7395390f 100644 --- a/example/network/lwip_iperf/sdkconfig.h +++ b/example/network/lwip_iperf/sdkconfig.h @@ -154,8 +154,9 @@ /* Optimization options */ /* CONFIG_DEBUG_NOOPT is not set */ -/* CONFIG_DEBUG_CUSTOMOPT is not set */ -#define CONFIG_DEBUG_FULLOPT +#define CONFIG_DEBUG_CUSTOMOPT +/* CONFIG_DEBUG_FULLOPT is not set */ +#define CONFIG_DEBUG_OPTLEVEL "-O2" #define CONFIG_DEBUG_OPT_UNUSED_SECTIONS #define CONFIG_DEBUG_LINK_MAP /* CONFIG_CCACHE is not set */ diff --git a/example/network/lwip_iperf/src/cmd_lwip_iperf.c b/example/network/lwip_iperf/src/cmd_lwip_iperf.c index 00005e5f9e95211dc71e260824237a4515081520..d9b64535c37039ab628e48c92c29f5a146ed8536 100644 --- a/example/network/lwip_iperf/src/cmd_lwip_iperf.c +++ b/example/network/lwip_iperf/src/cmd_lwip_iperf.c @@ -13,13 +13,14 @@ * * FilePath: cmd_lwip_iperf.c * Created Date: 2023-10-16 15:16:18 - * Last Modified: 2024-04-10 17:34:09 + * Last Modified: 2024-04-28 10:31:08 * Description: This file is for lwip iperf example cmd catalogue. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/10/16 first release + * 2.0 liuzhihong 2024/04/28 add no letter shell mode, adapt to auto-test system */ #include @@ -93,13 +94,13 @@ static int LwipIperfExampleEntry(int argc, char *argv[]) if (!strcmp(argv[1], "iperfc")) { LwipIperfExampleCheckState(); - ret = LwipIperfClientCreate(); + ret = FFreeRTOSLwipIperfClientTaskCreate(); init_flag_mask = CLIENT_EXAMPLE_RUNNING; } else if (!strcmp(argv[1], "iperfs")) { LwipIperfExampleCheckState(); - ret = LwipIperfServerCreate(); + ret = FFreeRTOSLwipIperfServerTaskCreate(); init_flag_mask = SERVER_EXAMPLE_RUNNING; } diff --git a/example/network/lwip_iperf/src/lwip_iperf_client_example.c b/example/network/lwip_iperf/src/lwip_iperf_client_example.c index 417e82b94cb53e3bc7515ac21854b2e45c001f73..daa5a0b81307ed3e53608a845446f59fd3d33930 100644 --- a/example/network/lwip_iperf/src/lwip_iperf_client_example.c +++ b/example/network/lwip_iperf/src/lwip_iperf_client_example.c @@ -13,14 +13,16 @@ * * FilePath: lwip_iperf_client_example.c * Created Date: 2023-10-18 14:30:04 - * Last Modified: 2023-12-29 14:31:20 + * Last Modified: 2024-04-29 15:21:41 * Description: This file is for lwip iperf client example function implementation. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/10/18 first release + * 2.0 liuzhihong 2024/04/28 add no letter shell mode, adapt to auto-test system */ + #include #include #include "strto.h" @@ -58,7 +60,14 @@ const ip_addr_t remote= IPADDR4_INIT_BYTES(192,168,4,50); .config.phy_duplex = LWIP_PORT_FULL_DUPLEX, \ .config.capability = LWIP_PORT_MODE_NAIVE, - +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) +enum +{ + LWIP_IPERF_CLIENT_EXAMPLE_SUCCESS = 0, + LWIP_IPERF_CLIENT_EXAMPLE_UNKNOWN_STATE = 1, + LWIP_IPERF_CLIENT_EXAMPLE_INIT_FAILURE = 2, +}; +static QueueHandle_t xQueue = NULL; typedef struct { @@ -109,9 +118,9 @@ static void SetIP(ip_addr_t* ipaddr,ip_addr_t* gw,ip_addr_t* netmask,u32 mac_id) } -int LwipIperfClientInitTask(void) +void LwipIperfClientTestTask(void) { - FError ret = FT_SUCCESS; + int task_res = LWIP_IPERF_CLIENT_EXAMPLE_SUCCESS; /* mac init */ for (int i = 0; i < MAC_NUM; i++) { @@ -121,7 +130,7 @@ int LwipIperfClientInitTask(void) board_mac_config[i].lwip_mac_config.name[0] = ETH_NAME_PREFIX; itoa(board_mac_config[i].lwip_mac_config.mac_instance, &(board_mac_config[i].lwip_mac_config.name[1]), 10); - /* mac ip addr set: char* -> ip_addr_t */ + /* mac ip addr set: char* -> ip_addr_t */ SetIP(&ipaddr,&gw,&netmask,i); /* ******************************************************************* */ @@ -130,7 +139,8 @@ int LwipIperfClientInitTask(void) if (!LwipPortAdd(netif_p, &ipaddr, &netmask, &gw, board_mac_config[i].mac_address, (UserConfig *)&board_mac_config[i])) { printf("Error adding N/W interface %d.\n\r",board_mac_config[i].lwip_mac_config.mac_instance); - return ERR_GENERAL; + task_res = LWIP_IPERF_CLIENT_EXAMPLE_INIT_FAILURE; + goto task_exit; } printf("LwipPortAdd mac_instance %d is over.\n\r",board_mac_config[i].lwip_mac_config.mac_instance); @@ -164,36 +174,64 @@ int LwipIperfClientInitTask(void) else { printf("Start iperf client test failed !!! \r\n"); - return ERR_GENERAL; + task_res = LWIP_IPERF_CLIENT_EXAMPLE_INIT_FAILURE; + goto task_exit; } - - if (ret == FT_SUCCESS) - { - printf("%s@%d: Lwip iperf example success !!! \r\n", __func__, __LINE__); - printf("[system_example_pass]\r\n"); - } - else - { - printf("%s@%d: Lwip iperf example failed !!!, ret = %d \r\n", __func__, __LINE__, ret); - } +task_exit: + xQueueSend(xQueue, &task_res, 0); vTaskDelete(NULL); - return 0; } -void LwipIperfClientCreate(void) +int FFreeRTOSLwipIperfClientTaskCreate(void) { - BaseType_t ret; - ret = xTaskCreate((TaskFunction_t)LwipIperfClientInitTask, /* 任务入口函数 */ - (const char *)"LwipIperfClientInitTask", /* 任务名字 */ - (uint16_t)2048, /* 任务栈大小 */ + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = LWIP_IPERF_CLIENT_EXAMPLE_UNKNOWN_STATE; + + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) + { + printf("xQueue create failed.\r\n"); + goto exit; + } + + xReturn = xTaskCreate((TaskFunction_t)LwipIperfClientTestTask, /* 任务入口函数 */ + (const char *)"LwipIperfClientTestTask", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ NULL); /* 任务控制块指针 */ + if (xReturn == pdFAIL) + { + printf("xTaskCreate LwipIpv4InitTask failed.\r\n"); + goto exit; + } - FASSERT_MSG(ret == pdPASS, "LwipTestCreate Task creation is failed"); + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + printf("xQueue receive timeout.\r\n"); + goto exit; + } + +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } + + if (task_res != LWIP_IPERF_CLIENT_EXAMPLE_SUCCESS) + { + printf("%s@%d: Lwip iperf client example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return task_res; + } + else + { + printf("%s@%d: Lwip iperf client example [success].\r\n", __func__, __LINE__); + return task_res; + } } void LwipIperfClientDeinit(void) diff --git a/example/network/lwip_iperf/src/lwip_iperf_server_example.c b/example/network/lwip_iperf/src/lwip_iperf_server_example.c index 45f517550e86c1f3d404dbf76a9ccb5e07e84fa7..5607c42ba47b83a8d9c88606d5a8a54b01754911 100644 --- a/example/network/lwip_iperf/src/lwip_iperf_server_example.c +++ b/example/network/lwip_iperf/src/lwip_iperf_server_example.c @@ -13,13 +13,14 @@ * * FilePath: lwip_iperf_server_example.c * Created Date: 2023-10-16 15:16:18 - * Last Modified: 2023-12-29 14:48:25 + * Last Modified: 2024-04-28 10:29:53 * Description: This file is for lwip iperf server example function implementation. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/10/16 first release + * 2.0 liuzhihong 2024/04/28 add no letter shell mode, adapt to auto-test system */ @@ -59,7 +60,14 @@ .config.phy_duplex = LWIP_PORT_FULL_DUPLEX, \ .config.capability = LWIP_PORT_MODE_NAIVE, - +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) +enum +{ + LWIP_IPERF_SERVER_EXAMPLE_SUCCESS = 0, + LWIP_IPERF_SERVER_EXAMPLE_UNKNOWN_STATE = 1, + LWIP_IPERF_SERVER_EXAMPLE_INIT_FAILURE = 2, +}; +static QueueHandle_t xQueue = NULL; typedef struct { @@ -110,9 +118,9 @@ static void SetIP(ip_addr_t* ipaddr,ip_addr_t* gw,ip_addr_t* netmask,u32 mac_id) } -int LwipIperfServerInitTask(void) +void LwipIperfServerTestTask(void) { - FError ret = FT_SUCCESS; + int task_res = LWIP_IPERF_SERVER_EXAMPLE_SUCCESS; /* mac init */ for (int i = 0; i < MAC_NUM; i++) { @@ -122,7 +130,7 @@ int LwipIperfServerInitTask(void) board_mac_config[i].lwip_mac_config.name[0] = ETH_NAME_PREFIX; itoa(board_mac_config[i].lwip_mac_config.mac_instance, &(board_mac_config[i].lwip_mac_config.name[1]), 10); - /* mac ip addr set: char* -> ip_addr_t */ + /* mac ip addr set: char* -> ip_addr_t */ SetIP(&ipaddr,&gw,&netmask,i); /* ******************************************************************* */ @@ -131,7 +139,8 @@ int LwipIperfServerInitTask(void) if (!LwipPortAdd(netif_p, &ipaddr, &netmask, &gw, board_mac_config[i].mac_address, (UserConfig *)&board_mac_config[i])) { printf("Error adding N/W interface %d.\n\r",board_mac_config[i].lwip_mac_config.mac_instance); - return ERR_GENERAL; + task_res = LWIP_IPERF_SERVER_EXAMPLE_INIT_FAILURE; + goto task_exit; } printf("LwipPortAdd mac_instance %d is over.\n\r",board_mac_config[i].lwip_mac_config.mac_instance); @@ -164,34 +173,63 @@ int LwipIperfServerInitTask(void) else { printf("Start iperf server failed !!! \r\n"); - return ERR_GENERAL; - } - - if (ret == FT_SUCCESS) - { - printf("%s@%d: Lwip iperf example success !!! \r\n", __func__, __LINE__); - printf("[system_example_pass]\r\n"); - } - else - { - printf("%s@%d: Lwip iperf example failed !!!, ret = %d \r\n", __func__, __LINE__, ret); + task_res = LWIP_IPERF_SERVER_EXAMPLE_INIT_FAILURE; + goto task_exit; } +task_exit: + xQueueSend(xQueue, &task_res, 0); + vTaskDelete(NULL); - return 0; } -void LwipIperfServerCreate(void) +int FFreeRTOSLwipIperfServerTaskCreate(void) { - BaseType_t ret; - ret = xTaskCreate((TaskFunction_t)LwipIperfServerInitTask, /* 任务入口函数 */ - (const char *)"LwipIperfServerInitTask", /* 任务名字 */ - (uint16_t)2048, /* 任务栈大小 */ + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = LWIP_IPERF_SERVER_EXAMPLE_UNKNOWN_STATE; + + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) + { + printf("xQueue create failed.\r\n"); + goto exit; + } + + xReturn = xTaskCreate((TaskFunction_t)LwipIperfServerTestTask, /* 任务入口函数 */ + (const char *)"LwipIperfServerTestTask", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ NULL); /* 任务控制块指针 */ + if (xReturn == pdFAIL) + { + printf("xTaskCreate LwipIpv4InitTask failed.\r\n"); + goto exit; + } - FASSERT_MSG(ret == pdPASS, "LwipTestCreate Task creation is failed"); + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + printf("xQueue receive timeout.\r\n"); + goto exit; + } + +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } + + if (task_res != LWIP_IPERF_SERVER_EXAMPLE_SUCCESS) + { + printf("%s@%d: Lwip iperf server example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return task_res; + } + else + { + printf("%s@%d: Lwip iperf server example [success].\r\n", __func__, __LINE__); + return task_res; + } } void LwipIperfServerDeinit(void) diff --git a/example/network/lwip_startup/README.md b/example/network/lwip_startup/README.md index d2bbc2772b223b0ed7c8e3bb60ee13941f862790..47c1ecb9eeced7177fa0c189994db2c7a27ec82b 100644 --- a/example/network/lwip_startup/README.md +++ b/example/network/lwip_startup/README.md @@ -146,6 +146,21 @@ lwip dhcp ## 3. 如何解决问题 +- Q: 如何静态配置开发板的ip地址? +- A: ipv4地址在board_mac_config静态变量中修改如下成员变量即可: + +``` + .ipaddr="192.168.4.10", + .gw="192.168.4.1", + .netmask="255.255.255.0", +``` + +- A: ipv6地址在board_mac_config静态变量中修改如下成员变量即可: + +``` + .mac_address={0x98, 0x0e, 0x24, 0x00, 0x11, 0x1}, +``` + ## 4. 修改历史记录 v0.2.0 重构lwip diff --git a/example/network/lwip_startup/fig/dhcp_example_result.png b/example/network/lwip_startup/fig/dhcp_example_result.png index 773ef7d912cc2cbcaa179492150aec3ef05c025c..fc42311713748685e6c5f2207d6d791cda984df6 100644 Binary files a/example/network/lwip_startup/fig/dhcp_example_result.png and b/example/network/lwip_startup/fig/dhcp_example_result.png differ diff --git a/example/network/lwip_startup/fig/dhcp_ping.png b/example/network/lwip_startup/fig/dhcp_ping.png index 7230601263d685cb2a0f0208188c5185f0213adc..1bd4f4ba20f5595d49d9571f58ed82756feae70c 100644 Binary files a/example/network/lwip_startup/fig/dhcp_ping.png and b/example/network/lwip_startup/fig/dhcp_ping.png differ diff --git a/example/network/lwip_startup/fig/ipv4_example_result.png b/example/network/lwip_startup/fig/ipv4_example_result.png index aaef95678ae871a54ae7d1d8194544c9f4827198..e836d5ef807a127629e8136c843e48d920f9838c 100644 Binary files a/example/network/lwip_startup/fig/ipv4_example_result.png and b/example/network/lwip_startup/fig/ipv4_example_result.png differ diff --git a/example/network/lwip_startup/fig/ipv4_ping.png b/example/network/lwip_startup/fig/ipv4_ping.png index 4df451934d172b9bd0870228ad29d0d6c45937eb..8d4f26b4a6794dcfab32d82815f9b4198e9165f7 100644 Binary files a/example/network/lwip_startup/fig/ipv4_ping.png and b/example/network/lwip_startup/fig/ipv4_ping.png differ diff --git a/example/network/lwip_startup/fig/ipv6_example_result.png b/example/network/lwip_startup/fig/ipv6_example_result.png index 58430df17a976e77f92836761404ce7647fcbc0a..b1aa258280641b799bbb8d1158b821b739a3cbd4 100644 Binary files a/example/network/lwip_startup/fig/ipv6_example_result.png and b/example/network/lwip_startup/fig/ipv6_example_result.png differ diff --git a/example/network/lwip_startup/fig/ipv6_ping.png b/example/network/lwip_startup/fig/ipv6_ping.png index 901ff28ba80d18b4dabbe37e8fe58e4ef45f7b69..bb5fc7fca3713fa0d944ab31802db14eb678c1ab 100644 Binary files a/example/network/lwip_startup/fig/ipv6_ping.png and b/example/network/lwip_startup/fig/ipv6_ping.png differ diff --git a/example/network/lwip_startup/inc/lwip_dhcp_example.h b/example/network/lwip_startup/inc/lwip_dhcp_example.h index e136c731c714733608411c8fe7f70a7d00b14da0..5bf5dc0adc8ed0d1f293db49049ae26639e451bb 100644 --- a/example/network/lwip_startup/inc/lwip_dhcp_example.h +++ b/example/network/lwip_startup/inc/lwip_dhcp_example.h @@ -13,13 +13,14 @@ * * FilePath: lwip_dhcp_example.h * Created Date: 2023-11-21 15:59:57 - * Last Modified: 2023-11-21 16:01:05 + * Last Modified: 2024-04-26 15:52:15 * Description: This file is for lwip dhcp example function definition. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/12/26 first release + * 2.0 liuzhihong 2024/4/26 add no letter shell mode, adapt to auto-test system */ #ifndef LWIP_DHCP_EXAMPLE_H #define LWIP_DHCP_EXAMPLE_H @@ -42,7 +43,7 @@ extern "C" /************************** Function Prototypes ******************************/ /* entry function for lwip dhcp example */ -int LwipDhcpTestCreate(void); +int FFreeRTOSLwipDhcpTaskCreate(void); void LwipDhcpTestDeinit(void); #ifdef __cplusplus diff --git a/example/network/lwip_startup/inc/lwip_ipv4_example.h b/example/network/lwip_startup/inc/lwip_ipv4_example.h index 2f5828febfd4cae65436ccf9935bd82317fe2e61..5c2c5eb170946908d9a2e821f8dcb482331d497c 100644 --- a/example/network/lwip_startup/inc/lwip_ipv4_example.h +++ b/example/network/lwip_startup/inc/lwip_ipv4_example.h @@ -13,13 +13,14 @@ * * FilePath: lwip_ipv4_example.h * Created Date: 2023-11-21 16:00:10 - * Last Modified: 2023-11-21 16:01:20 + * Last Modified: 2024-04-26 15:52:28 * Description: This file is for lwip ipv4 example function definition. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/12/26 first release + * 2.0 liuzhihong 2024/4/26 add no letter shell mode, adapt to auto-test system */ #ifndef LWIP_IPV4_EXAMPLE_H #define LWIP_IPV4_EXAMPLE_H @@ -42,9 +43,8 @@ extern "C" /************************** Function Prototypes ******************************/ /* entry function for lwip ipv4 example */ -int LwipIpv4TestCreate(void); +int FFreeRTOSLwipIpv4TaskCreate(void); void LwipIpv4TestDeinit(void); - #ifdef __cplusplus } #endif diff --git a/example/network/lwip_startup/inc/lwip_ipv6_example.h b/example/network/lwip_startup/inc/lwip_ipv6_example.h index fc1c44568ca31df42b22bdbc4616a53310ded667..efb896c92676e01942a0337bf7d695149aa381d0 100644 --- a/example/network/lwip_startup/inc/lwip_ipv6_example.h +++ b/example/network/lwip_startup/inc/lwip_ipv6_example.h @@ -13,13 +13,14 @@ * * FilePath: lwip_ipv6_example.h * Created Date: 2023-11-21 16:00:22 - * Last Modified: 2023-11-21 16:01:23 + * Last Modified: 2024-04-26 15:52:43 * Description: This file is for lwip ipv6 example function definition. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/12/26 first release + * 2.0 liuzhihong 2024/4/26 add no letter shell mode, adapt to auto-test system */ #ifndef LWIP_IPV6_EXAMPLE_H #define LWIP_IPV6_EXAMPLE_H @@ -42,7 +43,7 @@ extern "C" /************************** Function Prototypes ******************************/ /* entry function for lwip ipv6 example */ -int LwipIpv6TestCreate(void); +int FFreeRTOSLwipIpv6TaskCreate(void); void LwipIpv6TestDeinit(void); #ifdef __cplusplus diff --git a/example/network/lwip_startup/main.c b/example/network/lwip_startup/main.c index 9e6e7d656fbe420bc02dfe8dc83bead0ceb7a848..5da7b22e0d55d397da2fde375a32393d427223ae 100644 --- a/example/network/lwip_startup/main.c +++ b/example/network/lwip_startup/main.c @@ -13,36 +13,74 @@ * * FilePath: main.c * Created Date: 2023-11-20 18:26:15 - * Last Modified: 2023-12-28 15:13:08 + * Last Modified: 2024-04-28 11:47:17 * Description: This file is for lwip startup example main functions. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/12/26 first release + * 2.0 liuzhihong 2024/4/26 add no letter shell mode, adapt to auto-test system */ #include #include "FreeRTOS.h" #include "task.h" -#include "shell_port.h" #include "lwip/tcpip.h" -int main() +#include "sdkconfig.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "shell_port.h" +#else +#include "lwip_dhcp_example.h" +#include "lwip_ipv4_example.h" +#include "lwip_ipv6_example.h" + +#define LWIP_STARTUP_EXAMPLE_TASK_PRIORITY 2 + +void LwipStartupExampleTaskEntry() +{ + /* example functions */ + FFreeRTOSLwipIpv4TaskCreate(); + LwipIpv4TestDeinit(); + + FFreeRTOSLwipIpv6TaskCreate(); + LwipIpv6TestDeinit(); + + FFreeRTOSLwipDhcpTaskCreate(); + LwipDhcpTestDeinit(); + + /* end flag */ + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif + +int main(void) { - BaseType_t ret = pdPASS; + BaseType_t ret = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ +#ifdef CONFIG_USE_LETTER_SHELL ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)LwipStartupExampleTaskEntry, /* 任务入口函数 */ + (const char *)"LwipStartupExampleTaskEntry", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)LWIP_STARTUP_EXAMPLE_TASK_PRIORITY, /* 任务优先级 */ + NULL); /* 任务句柄 */ +#endif if (ret != pdPASS) { goto FAIL_EXIT; } - + tcpip_init(NULL, NULL); - vTaskStartScheduler(); /* 启动任务,开启调度 */ + /* 启动任务,开启调度 */ + vTaskStartScheduler(); while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("Failed 0x%x.\r\n", ret); - - return 0; + printf("Failed,the ret value is 0x%x. \r\n", ret); + return -2; } \ No newline at end of file diff --git a/example/network/lwip_startup/src/cmd_lwip_startup.c b/example/network/lwip_startup/src/cmd_lwip_startup.c index c3ccb0262b93cecc108ccbe9a0cf52fd030779c0..fdbca17908150caece447bbd23d758b2cea35334 100644 --- a/example/network/lwip_startup/src/cmd_lwip_startup.c +++ b/example/network/lwip_startup/src/cmd_lwip_startup.c @@ -13,13 +13,14 @@ * * FilePath: cmd_lwip_startup.c * Created Date: 2023-11-21 11:06:40 - * Last Modified: 2024-04-03 15:42:24 + * Last Modified: 2024-04-26 15:52:43 * Description: This file is for lwip startup example cmd catalogue. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/12/26 first release + * 2.0 liuzhihong 2024/4/26 add no letter shell mode, adapt to auto-test system */ #include @@ -99,19 +100,19 @@ static int LwipStartupExampleEntry(int argc, char *argv[]) if (!strcmp(argv[1], "ipv4")) { LwipStartupExampleCheckState(); - ret = LwipIpv4TestCreate(); + ret = FFreeRTOSLwipIpv4TaskCreate(); init_flag_mask = IPV4_EXAMPLE_RUNNING; } else if (!strcmp(argv[1], "ipv6")) { LwipStartupExampleCheckState(); - ret = LwipIpv6TestCreate(); + ret = FFreeRTOSLwipIpv6TaskCreate(); init_flag_mask = IPV6_EXAMPLE_RUNNING; } else if (!strcmp(argv[1], "dhcp")) { LwipStartupExampleCheckState(); - ret = LwipDhcpTestCreate(); + ret = FFreeRTOSLwipDhcpTaskCreate(); init_flag_mask = DHCP_EXAMPLE_RUNNING; } diff --git a/example/network/lwip_startup/src/lwip_dhcp_example.c b/example/network/lwip_startup/src/lwip_dhcp_example.c index d4f78e687b753c0d508787b0a60f41f3b114a001..627be6b02015df0ea2a12954b8a95e70f76ea74f 100644 --- a/example/network/lwip_startup/src/lwip_dhcp_example.c +++ b/example/network/lwip_startup/src/lwip_dhcp_example.c @@ -13,13 +13,14 @@ * * FilePath: lwip_dhcp_example.c * Created Date: 2023-11-21 11:13:07 - * Last Modified: 2023-12-28 15:11:56 + * Last Modified: 2024-04-28 14:14:44 * Description: This file is for lwip dhcp example function implementation. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/12/26 first release + * 2.0 liuzhihong 2024/4/26 add no letter shell mode, adapt to auto-test system */ @@ -58,7 +59,15 @@ .config.phy_duplex = LWIP_PORT_FULL_DUPLEX, \ .config.capability = LWIP_PORT_MODE_NAIVE, - +#define TIMER_OUT (pdMS_TO_TICKS(10000UL)) +enum +{ + LWIP_DHCP_EXAMPLE_SUCCESS = 0, + LWIP_DHCP_EXAMPLE_UNKNOWN_STATE = 1, + LWIP_DHCP_EXAMPLE_INIT_FAILURE = 2, + LWIP_DHCP_EXAMPLE_DHCP_RUN_FAILURE = 3, +}; +static QueueHandle_t xQueue = NULL; typedef struct { @@ -110,9 +119,25 @@ static void SetIP(ip_addr_t* ipaddr,ip_addr_t* gw,ip_addr_t* netmask,u32 mac_id) } -int LwipDhcpInitTask(void) +static int DhcpService_Is_Sucess() +{ + struct netif *netif; + char * ip_addr; + for (int i = 0; i < MAC_NUM; i++) + { + netif = LwipPortGetByName(board_mac_config[i].lwip_mac_config.name); + ip_addr = ipaddr_ntoa(&(netif->ip_addr)); + + if(strcmp(ip_addr,board_mac_config[i].ipaddr) == 0) + return 0; + } + + return 1; +} + +void LwipDhcpInitTask(void) { - FError ret = FT_SUCCESS; + int task_res = LWIP_DHCP_EXAMPLE_SUCCESS; /* mac init */ for (int i = 0; i < MAC_NUM; i++) { @@ -121,7 +146,7 @@ int LwipDhcpInitTask(void) board_mac_config[i].lwip_mac_config.name[0] = ETH_NAME_PREFIX; itoa(board_mac_config[i].lwip_mac_config.mac_instance, &(board_mac_config[i].lwip_mac_config.name[1]), 10); - /* mac ip addr set: char* -> ip_addr_t */ + /* mac ip addr set: char* -> ip_addr_t */ SetIP(&ipaddr,&gw,&netmask,i); /* ******************************************************************* */ @@ -131,7 +156,8 @@ int LwipDhcpInitTask(void) if (!LwipPortAdd(netif_p, &ipaddr, &netmask, &gw, board_mac_config[i].mac_address, (UserConfig *)&board_mac_config[i])) { printf("Error adding N/W interface %d.\n\r",board_mac_config[i].lwip_mac_config.mac_instance); - return ERR_GENERAL; + task_res = LWIP_DHCP_EXAMPLE_INIT_FAILURE; + goto task_exit; } printf("LwipPortAdd mac_instance %d is over.\n\r",board_mac_config[i].lwip_mac_config.mac_instance); @@ -155,32 +181,69 @@ int LwipDhcpInitTask(void) } printf("Network setup complete.\n"); - - if (ret == FT_SUCCESS) - { - printf("%s@%d: Lwip dhcp example success !!! \r\n", __func__, __LINE__); - printf("[system_example_pass]\r\n"); - } - else + + vTaskDelay(10000); + if(!DhcpService_Is_Sucess()) { - printf("%s@%d: Lwip dhcp example failed !!!, ret = %d \r\n", __func__, __LINE__, ret); + printf("Dhcp service is not in effect\r\n"); + task_res = LWIP_DHCP_EXAMPLE_DHCP_RUN_FAILURE; + goto task_exit; } + printf("Dhcp service is in effect\r\n"); + +task_exit: + xQueueSend(xQueue, &task_res, 0); vTaskDelete(NULL); - return 0; } -void LwipDhcpTestCreate(void) +int FFreeRTOSLwipDhcpTaskCreate(void) { - BaseType_t ret; - ret = xTaskCreate((TaskFunction_t)LwipDhcpInitTask, /* 任务入口函数 */ + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = LWIP_DHCP_EXAMPLE_UNKNOWN_STATE; + + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) + { + printf("xQueue create failed.\r\n"); + goto exit; + } + + xReturn = xTaskCreate((TaskFunction_t)LwipDhcpInitTask, /* 任务入口函数 */ (const char *)"LwipDhcpInitTask", /* 任务名字 */ - (uint16_t)2048, /* 任务栈大小 */ + (uint16_t)4096, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ NULL); /* 任务控制块指针 */ + if (xReturn == pdFAIL) + { + printf("xTaskCreate LwipDhcpInitTask failed.\r\n"); + goto exit; + } + + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + printf("xQueue receive timeout.\r\n"); + goto exit; + } - FASSERT_MSG(ret == pdPASS, "LwipTestCreate Task creation is failed"); +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } + + if (task_res != LWIP_DHCP_EXAMPLE_SUCCESS) + { + printf("%s@%d: Lwip dhcp example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return task_res; + } + else + { + printf("%s@%d: Lwip dhcp example [success].\r\n", __func__, __LINE__); + return task_res; + } } void LwipDhcpTestDeinit(void) diff --git a/example/network/lwip_startup/src/lwip_ipv4_example.c b/example/network/lwip_startup/src/lwip_ipv4_example.c index b629d829596cfd23f54657a54f3b0c8da2ab9a41..c8109e49b498e69c05fd8558bee4da388b68769a 100644 --- a/example/network/lwip_startup/src/lwip_ipv4_example.c +++ b/example/network/lwip_startup/src/lwip_ipv4_example.c @@ -13,13 +13,14 @@ * * FilePath: lwip_ipv4_example.c * Created Date: 2023-11-21 11:12:04 - * Last Modified: 2023-12-28 15:12:06 + * Last Modified: 2024-04-26 15:53:23 * Description: This file is for lwip ipv4 example function implementation. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/12/26 first release + * 2.0 liuzhihong 2024/4/26 add no letter shell mode, adapt to auto-test system */ #include @@ -55,8 +56,15 @@ .config.phy_speed = LWIP_PORT_SPEED_1000M, \ .config.phy_duplex = LWIP_PORT_FULL_DUPLEX, \ .config.capability = LWIP_PORT_MODE_NAIVE, - - + +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) +enum +{ + LWIP_IPV4_EXAMPLE_SUCCESS = 0, + LWIP_IPV4_EXAMPLE_UNKNOWN_STATE = 1, + LWIP_IPV4_EXAMPLE_INIT_FAILURE = 2, +}; +static QueueHandle_t xQueue = NULL; typedef struct { @@ -107,9 +115,9 @@ static void SetIP(ip_addr_t* ipaddr,ip_addr_t* gw,ip_addr_t* netmask,u32 mac_id) } -int LwipIpv4InitTask(void) +void LwipIpv4InitTask(void) { - FError ret = FT_SUCCESS; + int task_res = LWIP_IPV4_EXAMPLE_SUCCESS; /* mac init */ for (int i = 0; i < MAC_NUM; i++) { @@ -128,7 +136,8 @@ int LwipIpv4InitTask(void) if (!LwipPortAdd(netif_p, &ipaddr, &netmask, &gw, board_mac_config[i].mac_address, (UserConfig *)&board_mac_config[i])) { printf("Error adding N/W interface %d.\n\r",board_mac_config[i].lwip_mac_config.mac_instance); - return ERR_GENERAL; + task_res = LWIP_IPV4_EXAMPLE_INIT_FAILURE; + goto task_exit; } printf("LwipPortAdd mac_instance %d is over.\n\r",board_mac_config[i].lwip_mac_config.mac_instance); @@ -150,34 +159,61 @@ int LwipIpv4InitTask(void) } } - printf("Network setup complete.\n"); - if (ret == FT_SUCCESS) - { - printf("%s@%d: Lwip ipv4 example success !!! \r\n", __func__, __LINE__); - printf("[system_example_pass]\r\n"); - } - else - { - printf("%s@%d: Lwip ipv4 example failed !!!, ret = %d \r\n", __func__, __LINE__, ret); - } +task_exit: + xQueueSend(xQueue, &task_res, 0); vTaskDelete(NULL); - return 0; } -void LwipIpv4TestCreate(void) +int FFreeRTOSLwipIpv4TaskCreate(void) { - BaseType_t ret; - ret = xTaskCreate((TaskFunction_t)LwipIpv4InitTask, /* 任务入口函数 */ + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = LWIP_IPV4_EXAMPLE_UNKNOWN_STATE; + + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) + { + printf("xQueue create failed.\r\n"); + goto exit; + } + + xReturn = xTaskCreate((TaskFunction_t)LwipIpv4InitTask, /* 任务入口函数 */ (const char *)"LwipIpv4InitTask", /* 任务名字 */ (uint16_t)4096, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ NULL); /* 任务控制块指针 */ + if (xReturn == pdFAIL) + { + printf("xTaskCreate LwipIpv4InitTask failed.\r\n"); + goto exit; + } - FASSERT_MSG(ret == pdPASS, "LwipTestCreate Task creation is failed"); + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + printf("xQueue receive timeout.\r\n"); + goto exit; + } + +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } + + if (task_res != LWIP_IPV4_EXAMPLE_SUCCESS) + { + printf("%s@%d: Lwip ipv4 example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return task_res; + } + else + { + printf("%s@%d: Lwip ipv4 example [success].\r\n", __func__, __LINE__); + return task_res; + } } void LwipIpv4TestDeinit(void) diff --git a/example/network/lwip_startup/src/lwip_ipv6_example.c b/example/network/lwip_startup/src/lwip_ipv6_example.c index 42c686066525b1478e2a5c66d1747b6580ed91e1..acbc6ebc28b6b7695ae34200172760ddbe28a4ac 100644 --- a/example/network/lwip_startup/src/lwip_ipv6_example.c +++ b/example/network/lwip_startup/src/lwip_ipv6_example.c @@ -13,13 +13,14 @@ * * FilePath: lwip_ipv6_example.c * Created Date: 2023-11-21 11:12:18 - * Last Modified: 2023-12-28 15:12:11 + * Last Modified: 2024-04-26 15:53:15 * Description: This file is for lwip ipv6 example function implementation. * * Modify History: * Ver Who Date Changes * ----- ---------- -------- --------------------------------- * 1.0 liuzhihong 2023/12/26 first release + * 2.0 liuzhihong 2024/4/26 add no letter shell mode, adapt to auto-test system */ #include @@ -56,7 +57,15 @@ .config.phy_speed = LWIP_PORT_SPEED_1000M, \ .config.phy_duplex = LWIP_PORT_FULL_DUPLEX, \ .config.capability = LWIP_PORT_MODE_COPY_ALL_FRAMES, - + +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) +enum +{ + LWIP_IPV6_EXAMPLE_SUCCESS = 0, + LWIP_IPV6_EXAMPLE_UNKNOWN_STATE = 1, + LWIP_IPV6_EXAMPLE_INIT_FAILURE = 2, +}; +static QueueHandle_t xQueue = NULL; typedef struct @@ -108,9 +117,9 @@ static void SetIP(ip_addr_t* ipaddr,ip_addr_t* gw,ip_addr_t* netmask,u32 mac_id) } -int LwipIpv6InitTask(void) +void LwipIpv6InitTask(void) { - FError ret = FT_SUCCESS; + int task_res = LWIP_IPV6_EXAMPLE_SUCCESS; /* mac init */ for (int i = 0; i < MAC_NUM; i++) { @@ -120,7 +129,7 @@ int LwipIpv6InitTask(void) itoa(board_mac_config[i].lwip_mac_config.mac_instance, &(board_mac_config[i].lwip_mac_config.name[1]), 10); - /* mac ip addr set: char* -> ip_addr_t */ + /* mac ip addr set: char* -> ip_addr_t */ SetIP(&ipaddr,&gw,&netmask,i); /* ******************************************************************* */ @@ -130,7 +139,8 @@ int LwipIpv6InitTask(void) if (!LwipPortAdd(netif_p, &ipaddr, &netmask, &gw, board_mac_config[i].mac_address, (UserConfig *)&board_mac_config[i])) { printf("Error adding N/W interface %d.\n\r",board_mac_config[i].lwip_mac_config.mac_instance); - return ERR_GENERAL; + task_res = LWIP_IPV6_EXAMPLE_INIT_FAILURE; + goto task_exit; } printf("LwipPortAdd mac_instance %d is over.\n\r",board_mac_config[i].lwip_mac_config.mac_instance); @@ -158,34 +168,61 @@ int LwipIpv6InitTask(void) } } - printf("Network setup complete.\n"); - - if (ret == FT_SUCCESS) - { - printf("%s@%d: Lwip ipv6 example success !!! \r\n", __func__, __LINE__); - printf("[system_example_pass]\r\n"); - } - else - { - printf("%s@%d: Lwip ipv6 example failed !!!, ret = %d \r\n", __func__, __LINE__, ret); - } + +task_exit: + xQueueSend(xQueue, &task_res, 0); vTaskDelete(NULL); - return 0; } -void LwipIpv6TestCreate(void) +int FFreeRTOSLwipIpv6TaskCreate(void) { - BaseType_t ret; - ret = xTaskCreate((TaskFunction_t)LwipIpv6InitTask, /* 任务入口函数 */ + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = LWIP_IPV6_EXAMPLE_UNKNOWN_STATE; + + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) + { + printf("xQueue create failed.\r\n"); + goto exit; + } + + xReturn = xTaskCreate((TaskFunction_t)LwipIpv6InitTask, /* 任务入口函数 */ (const char *)"LwipIpv6InitTask", /* 任务名字 */ - (uint16_t)2048, /* 任务栈大小 */ + (uint16_t)4096, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ NULL); /* 任务控制块指针 */ + if (xReturn == pdFAIL) + { + printf("xTaskCreate LwipIpv6InitTask failed.\r\n"); + goto exit; + } + + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + printf("xQueue receive timeout.\r\n"); + goto exit; + } + +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } - FASSERT_MSG(ret == pdPASS, "LwipTestCreate Task creation is failed"); + if (task_res != LWIP_IPV6_EXAMPLE_SUCCESS) + { + printf("%s@%d: Lwip ipv6 example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return task_res; + } + else + { + printf("%s@%d: Lwip ipv6 example [success].\r\n", __func__, __LINE__); + return task_res; + } } void LwipIpv6TestDeinit(void) diff --git a/example/network/sockets/udp_multicast/README.md b/example/network/sockets/udp_multicast/README.md index 27ffe83010cd1a735746cc396eb2628a974fd358..119260134a0b70e05642e9ce6829c6821406f19b 100644 --- a/example/network/sockets/udp_multicast/README.md +++ b/example/network/sockets/udp_multicast/README.md @@ -9,7 +9,7 @@ 本例程需要用到 - Phytium开发板(E2000) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 diff --git a/example/network/wlan/README.md b/example/network/wlan/README.md index 7dba9353765baa4af5ce9cd3e3ebf91d96c65556..f4283dc6168713705315a51c759c98a4b85d688e 100644 --- a/example/network/wlan/README.md +++ b/example/network/wlan/README.md @@ -93,6 +93,8 @@ bootelf -p 0x90100000 ### 2.4 输出与实验现象 +> 非letter shell模式下仅支持wifi扫描功能测试。 + #### 2.4.1 Station 模式连接 AP 热点 - 准备一个 AP 热点,例如路由器或者手机热点,本例程 中用小米手机产生一个 AP 热点供开发板连接 @@ -158,4 +160,6 @@ wlan_ap start >记录例程的重大修改记录,标明修改发生的版本号
-- v1.2.1 首次合入 \ No newline at end of file +- v1.2.1 首次合入 + +- v2.0.0 增加非letter shell模式;增加wlan deinit过程。 \ No newline at end of file diff --git a/example/network/wlan/inc/wlan_ap_config.h b/example/network/wlan/inc/wlan_ap_config.h index be0126e5a6b1714a026c851e9d4bab5e1de1eec5..a5b00f0521a1fc21928913ec408d1e9b91e6d79b 100644 --- a/example/network/wlan/inc/wlan_ap_config.h +++ b/example/network/wlan/inc/wlan_ap_config.h @@ -29,6 +29,7 @@ extern "C" { #endif + /***************************** Include Files *********************************/ /************************** Constant Definitions *****************************/ diff --git a/example/network/wlan/inc/wlan_common.h b/example/network/wlan/inc/wlan_common.h index b749bd2979b4bbce807d18b43cf89817f65d24c1..71f7e1045185d8b1d40f06435ff5c7399921fe72 100644 --- a/example/network/wlan/inc/wlan_common.h +++ b/example/network/wlan/inc/wlan_common.h @@ -98,6 +98,12 @@ typedef enum */ FWlanRetStatus FWlanInit(void); +/** +* @brief Stop and deinit Wi-Fi driver and WPL layer. +*/ +void FWlanDeinit(void); + + /** * @brief Start Wi-Fi driver and register an application link state callback. * Set WPL layer state to WLAN_STATE_STARTED. diff --git a/example/network/wlan/inc/wlan_station_scan.h b/example/network/wlan/inc/wlan_station_scan.h index d9666843c8d0f2462c0a0beb58ec548546d9c5c0..25279c0fe29753ea98614ac9a3b91f59367b9526 100644 --- a/example/network/wlan/inc/wlan_station_scan.h +++ b/example/network/wlan/inc/wlan_station_scan.h @@ -38,8 +38,9 @@ extern "C" /***************** Macros (Inline Functions) Definitions *********************/ /************************** Function Prototypes ******************************/ -BaseType_t FFreeRTOSWlanStationScanInit(void); +BaseType_t FFreeRTOSWlanStationScanTaskCreate(void); +void WlanExampleEntry(void); /*****************************************************************************/ #ifdef __cplusplus diff --git a/example/network/wlan/main.c b/example/network/wlan/main.c index 4e366cf57fb7f566dd6205473c2bc824a7de825d..2bc117ee161233d142d640d190db96e945776e20 100644 --- a/example/network/wlan/main.c +++ b/example/network/wlan/main.c @@ -26,18 +26,32 @@ #include "FreeRTOS.h" #include "task.h" #include "ftypes.h" +#include "wlan_station_scan.h" +#include "wlan_common.h" +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" +#endif int main() { BaseType_t xReturn = pdPASS; - +#ifdef CONFIG_USE_LETTER_SHELL xReturn = LSUserShellTask(); if (xReturn != pdPASS) { goto FAIL_EXIT; } +#else + + xReturn = xTaskCreate((TaskFunction_t)WlanExampleEntry, + (const char *)"WlanExampleEntry", + (uint16_t)4096, + NULL, + (UBaseType_t)2, + NULL); + +#endif vTaskStartScheduler(); /* 启动任务,开启调度 */ @@ -46,4 +60,11 @@ int main() FAIL_EXIT: printf("Failed,the xReturn value is 0x%x. \r\n", xReturn); return 0; +} + +void WlanExampleEntry(void) +{ + FFreeRTOSWlanStationScanTaskCreate(); + printf("[test_end].\r\n"); + vTaskDelete(NULL); } \ No newline at end of file diff --git a/example/network/wlan/src/cmd_ap.c b/example/network/wlan/src/cmd_ap.c index 7fbcfeae0d5cff1286d66605f621ba46072fdd2e..4bbfe7fe2af55a6f3022f5fa604a73de8ae68f65 100644 --- a/example/network/wlan/src/cmd_ap.c +++ b/example/network/wlan/src/cmd_ap.c @@ -21,6 +21,7 @@ * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/8/26 first commit */ + /***************************** Include Files *********************************/ #include #include @@ -28,7 +29,9 @@ #include "sdkconfig.h" #include "FreeRTOS.h" +#include "wlan_common.h" +#ifdef CONFIG_USE_LETTER_SHELL #include "../src/shell.h" #include "wlan_ap_config.h" /************************** Constant Definitions *****************************/ @@ -69,4 +72,8 @@ static int APCmdEntry(int argc, char *argv[]) return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), wlan_ap, APCmdEntry, wireless ap functions); \ No newline at end of file + +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), wlan_ap, APCmdEntry, wireless ap functions); + +#endif + diff --git a/example/network/wlan/src/cmd_station.c b/example/network/wlan/src/cmd_station.c index f1e62ba9ac7108e4f63adf9e0aad10aa10e08aa5..0c9878ce6878bc919f74c00e747853e5e0263660 100644 --- a/example/network/wlan/src/cmd_station.c +++ b/example/network/wlan/src/cmd_station.c @@ -22,16 +22,21 @@ * 1.0 zhugengyu 2022/8/26 first commit */ /***************************** Include Files *********************************/ + #include #include #include "strto.h" #include "sdkconfig.h" #include "FreeRTOS.h" +#include "task.h" +#include "wlan_station_scan.h" +#include "wlan_common.h" +#ifdef CONFIG_USE_LETTER_SHELL #include "../src/shell.h" -#include "wlan_station_scan.h" #include "wlan_station_connect.h" + /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ @@ -66,7 +71,7 @@ static int WlanCmdEntry(int argc, char *argv[]) if (!strcmp(argv[1], "scan")) { - if (pdPASS != FFreeRTOSWlanStationScanInit()) + if (pdPASS != FFreeRTOSWlanStationScanTaskCreate()) { return -2; } @@ -98,4 +103,7 @@ static int WlanCmdEntry(int argc, char *argv[]) return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), wlan_station, WlanCmdEntry, wlan functions); \ No newline at end of file + +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), wlan_station, WlanCmdEntry, wlan functions); + +#endif diff --git a/example/network/wlan/src/wlan_ap_config.c b/example/network/wlan/src/wlan_ap_config.c index 43cd1a5a79f994732ecc94694db7d636fe6accd7..c9eb579be6da7b0ba62229721fb5079ba42e71f2 100644 --- a/example/network/wlan/src/wlan_ap_config.c +++ b/example/network/wlan/src/wlan_ap_config.c @@ -21,6 +21,8 @@ * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2023/10/19 first commit */ + + /***************************** Include Files *********************************/ #include #include @@ -35,6 +37,7 @@ #include "wlan_common.h" #include "wlan_ap_config.h" +#ifdef CONFIG_USE_LETTER_SHELL /************************** Constant Definitions *****************************/ /* Parameters that apply to AP mode only */ #ifndef WIFI_AP_CHANNEL @@ -233,7 +236,6 @@ static void StartAP(void *arg) /* Credentials from last time have been found. The board will attempt to * connect to this network as a client */ printf("[i] AP SSID: %s, Password: %s, Security: %s\r\n", ssid, password, security); - memset(g_board_state.ssid, 0U, sizeof(g_board_state.ssid)); memset(g_board_state.password, 0U, sizeof(g_board_state.password)); memset(g_board_state.security, 0U, sizeof(g_board_state.security)); @@ -298,6 +300,8 @@ task_exit: BaseType_t FFreeRTOSStartAP(void) { /* Create the main Task */ + FWlanStopAP(); + FWlanDeinit(); if (xTaskCreate(StartAP, "StartAP", 4096, @@ -310,4 +314,5 @@ BaseType_t FFreeRTOSStartAP(void) } return pdPASS; -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/example/network/wlan/src/wlan_common.c b/example/network/wlan/src/wlan_common.c index 6543d476eff7ed966c18e39d21273063b141bb71..758243b983bafe8ed178810e25b8de5cccaa9121 100644 --- a/example/network/wlan/src/wlan_common.c +++ b/example/network/wlan/src/wlan_common.c @@ -4,7 +4,6 @@ * * SPDX-License-Identifier: BSD-3-Clause */ - #include "wlan_bt_fw.h" #include "wlan.h" #include "wifi.h" @@ -203,6 +202,23 @@ FWlanRetStatus FWlanInit(void) return status; } +void FWlanDeinit(void) +{ + if(s_wlan_state == WLAN_STATE_NOT_INITIALIZED) + { + return; + } + else + { + if(s_wlan_state == WLAN_STATE_STARTED) + { + FWlanStop(); + } + wlan_deinit(WLAN_ACTIVE); + s_wlan_state = WLAN_STATE_NOT_INITIALIZED; + } +} + FWlanRetStatus FWlanStart(FWlanLinkLostCb callbackFunction) { FWlanRetStatus status = FWLAN_RET_SUCCESS; diff --git a/example/network/wlan/src/wlan_station_connect.c b/example/network/wlan/src/wlan_station_connect.c index f50ba11f8ad6fb0445d9e036ffd1a614cec1584c..5f6af5d11582ce3d475ac4de8c85c849c8d23ad5 100644 --- a/example/network/wlan/src/wlan_station_connect.c +++ b/example/network/wlan/src/wlan_station_connect.c @@ -21,6 +21,7 @@ * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2023/10/19 first commit */ + /***************************** Include Files *********************************/ #include #include diff --git a/example/network/wlan/src/wlan_station_scan.c b/example/network/wlan/src/wlan_station_scan.c index df8417571936ac884a8aeb77911198e15fac172d..a39c15c1fdee18f19f059fb2a56edde44e2bff8f 100644 --- a/example/network/wlan/src/wlan_station_scan.c +++ b/example/network/wlan/src/wlan_station_scan.c @@ -13,33 +13,42 @@ * * FilePath: wlan_station_scan.c * Date: 2022-07-12 09:53:00 - * LastEditTime: 2022-07-12 09:53:02 + * LastEditTime: 2024-04-30 09:53:02 * Description:  This file is for providing functions used in cmd_sf.c file. * * Modify History: * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2023/10/19 first commit + * 2.0 liyilun 2024/4/30 add no letter shell mode, adapt to auto test system */ /***************************** Include Files *********************************/ #include #include - #include "FreeRTOS.h" #include "task.h" - #include "fdebug.h" #include "fsleep.h" #include "fkernel.h" - +#include "fassert.h" +#include #include "wlan_common.h" #include "wlan_station_scan.h" + /************************** Constant Definitions *****************************/ /************************** Variable Definitions *****************************/ +static QueueHandle_t xQueue = NULL; + /***************** Macros (Inline Functions) Definitions *********************/ +#define WR_TIMER_PERIOD pdMS_TO_TICKS(60000U) +#define FWLAN_DEBUG_TAG "FFreeRTOSWlan" +#define FWLAN_ERROR(format, ...) FT_DEBUG_PRINT_E(FWLAN_DEBUG_TAG, format, ##__VA_ARGS__) +#define FWLAN_WARN(format, ...) FT_DEBUG_PRINT_W(FWLAN_DEBUG_TAG, format, ##__VA_ARGS__) +#define FWLAN_INFO(format, ...) FT_DEBUG_PRINT_I(FWLAN_DEBUG_TAG, format, ##__VA_ARGS__) +#define FWLAN_DEBUG(format, ...) FT_DEBUG_PRINT_D(FWLAN_DEBUG_TAG, format, ##__VA_ARGS__) /************************** Function Prototypes ******************************/ /*****************************************************************************/ @@ -60,7 +69,6 @@ void WlanStationScanTask(void *param) { FWlanRetStatus result; char *scan_result; - result = FWlanInit(); if (result != FWLAN_RET_SUCCESS) { @@ -79,28 +87,56 @@ void WlanStationScanTask(void *param) if (scan_result == NULL) { printf("[!] FWlanScan: Failed to scan\r\n"); + result = FWLAN_NOT_FOUND; goto task_exit; } vPortFree(scan_result); task_exit: + xQueueSend(xQueue, &result, 0); vTaskDelete(NULL); } -BaseType_t FFreeRTOSWlanStationScanInit(void) +BaseType_t FFreeRTOSWlanStationScanTaskCreate(void) { + xQueue = xQueueCreate(1, sizeof(int)); + if(xQueue == NULL) + { + FWLAN_ERROR("xQueue Create failed."); + goto err_ret; + } + BaseType_t xReturn; + int task_ret; /* Create the main Task */ - if (xTaskCreate(WlanStationScanTask, + FWlanDeinit(); + xReturn = xTaskCreate(WlanStationScanTask, "WlanStationScanTask", 4096, NULL, (UBaseType_t)configMAX_PRIORITIES - 1, - NULL) != pdPASS) + NULL); + if(xReturn != pdPASS) { - printf("[!] MAIN Task creation failed!\r\n"); - return pdFAIL; + FWLAN_ERROR("WlanStationScanTask create failed."); + goto err_ret; } - return pdPASS; + xReturn = xQueueReceive(xQueue, &task_ret, WR_TIMER_PERIOD); + vQueueDelete(xQueue); + + if(xReturn != pdPASS) + { + FWLAN_ERROR("xQueue receive failed.\r\n"); + goto err_ret; + } + + if(task_ret == FWLAN_RET_SUCCESS) + { + printf("%s@%d: Wlan scan example [success].\r\n", __func__, __LINE__); + return pdPASS; + } +err_ret: + printf("%s@%d: Wlan scan example [failure].\r\n", __func__, __LINE__); + return pdFAIL; } \ No newline at end of file diff --git a/example/peripheral/adc/README.md b/example/peripheral/adc/README.md index e4a96b0e6c43f8824edd5ee2ab01ec11bc1dfb22..0824663e3357c584b99eb61fa622983a64a7d4bb 100644 --- a/example/peripheral/adc/README.md +++ b/example/peripheral/adc/README.md @@ -15,7 +15,7 @@ 本例程需要用到 - Phytium开发板(E2000D) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 diff --git a/example/peripheral/can/can/README.md b/example/peripheral/can/can/README.md index 4070de28a9d070d978395ae1fffb773f4b45d4ed..25f89ec2dd91988d9621f365fa537cf84b03a201 100644 --- a/example/peripheral/can/can/README.md +++ b/example/peripheral/can/can/README.md @@ -42,7 +42,7 @@ CAN过滤功能测试例程 (can_id_filter_example.c) 本例程需要用到 - Phytium开发板(E2000D/E2000Q/D2000/FT2000-4) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -136,6 +136,7 @@ bootelf -p 0x90100000 ## 3. 如何解决问题 - 使用can0和can1进行回环测试时,需要将can0和can1的H和L信号线分别进行短接 -- ft2004和d2000不支持id过滤功能的描述 +- FT2000/4和D2000不支持id过滤功能的描述 +- PhytiumPi不支持can功能的描述 ## 4. 修改历史记录 diff --git a/example/peripheral/can/can/src/can_id_filter_example.c b/example/peripheral/can/can/src/can_id_filter_example.c index 2b0e696fe05a3147ceb6c6ba8846834af35b10de..38ce3cba428f06ec89494c4735cc90d6be6e09d1 100644 --- a/example/peripheral/can/can/src/can_id_filter_example.c +++ b/example/peripheral/can/can/src/can_id_filter_example.c @@ -29,7 +29,6 @@ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "timers.h" #include "fcan.h" #include "fcan_os.h" #include "fcpu_info.h" @@ -55,8 +54,8 @@ enum }; /* can frame config */ -#define CanFilterMode1 1 -#define CanFilterMode2 2 +#define CAN_FILTER_MODE_1 1 +#define CAN_FILTER_MODE_2 2 #define FCAN_SEND_LENGTH 8 #define FCAN_FILTER_MODE1_ID 0x0F #define FCAN_FILTER_MODE1_MASK 0x00 @@ -87,8 +86,6 @@ static FFreeRTOSCan *os_can_ctrl_p[FCAN_NUM]; static FCanFrame send_frame[FCAN_NUM]; static FCanFrame recv_frame[FCAN_NUM]; -static u32 recv_count[FCAN_NUM] = {0}; - static FError FFreeRTOSCanSendThenRecvData(int mode); static FError FFreeRTOSCanRecvData(int mode, FCanQueueData * xReceiveStructure); static void FFreeRTOSCanDelete(void); @@ -386,6 +383,7 @@ static FError FFreeRTOSCanRecvData(int mode, FCanQueueData * xReceiveStructure) FError ret = FCAN_SUCCESS; FFreeRTOSCan *os_can_p; u32 instance_id = FCAN0_ID; + static u32 recv_count[FCAN_NUM] = {0}; os_can_p = xReceiveStructure->os_can_p; instance_id = os_can_p->can_ctrl.config.instance_id; @@ -407,12 +405,12 @@ static FError FFreeRTOSCanRecvData(int mode, FCanQueueData * xReceiveStructure) } FCAN_TEST_DEBUG("The frame id:0x%02x was receved successfully.", recv_frame[instance_id].canid); - if ( (mode == CanFilterMode1) && (recv_frame[instance_id].canid == FCAN_FILTER_MODE1_ID) ) + if ( (mode == CAN_FILTER_MODE_1) && (recv_frame[instance_id].canid == FCAN_FILTER_MODE1_ID) ) { printf("can%d -> can%d: Filter mode1 test completed.\r\n", FCAN1_ID - instance_id, instance_id); return ret; } - else if ( (mode == CanFilterMode2) && ((recv_frame[instance_id].canid & FCAN_FILTER_MODE2_ID) == FCAN_FILTER_MODE2_ID) ) + else if ( (mode == CAN_FILTER_MODE_2) && ((recv_frame[instance_id].canid & FCAN_FILTER_MODE2_ID) == FCAN_FILTER_MODE2_ID) ) { recv_count[instance_id]++; if ( recv_count[instance_id] == FCAN_FILTER_MODE2_CNT ) @@ -422,6 +420,13 @@ static FError FFreeRTOSCanRecvData(int mode, FCanQueueData * xReceiveStructure) return ret; } } + else + { + /* 过滤失败 */ + FCAN_TEST_ERROR("can%d recv id 0x%02x should not be received!!!", instance_id, recv_frame[instance_id].canid); + ret = CAN_DATA_FAILURE; + return ret; + } } return ret; @@ -444,7 +449,7 @@ BaseType_t FFreeRTOSCanCreateFilterTestTask(void) xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanFilterTask, /* 任务入口函数 */ (const char *)"FFreeRTOSCanFilterMode1Task", /* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ - (void *)CanFilterMode1, /* 任务入口函数参数 */ + (void *)CAN_FILTER_MODE_1, /* 任务入口函数参数 */ (UBaseType_t)CAN_FILTER_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ if (xReturn == pdFAIL) @@ -464,7 +469,7 @@ BaseType_t FFreeRTOSCanCreateFilterTestTask(void) xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanFilterTask, /* 任务入口函数 */ (const char *)"FFreeRTOSCanFilterMode2Task", /* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ - (void *)CanFilterMode2, /* 任务入口函数参数 */ + (void *)CAN_FILTER_MODE_2, /* 任务入口函数参数 */ (UBaseType_t)CAN_FILTER_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ if (xReturn == pdFAIL) diff --git a/example/peripheral/can/can/src/can_intr_loopback_mode_example.c b/example/peripheral/can/can/src/can_intr_loopback_mode_example.c index 66e70cb86f78c6a09ddace2ae1bfede15a69f713..1a1118355f8708c09b6c38de8bf9ce96a4fac806 100644 --- a/example/peripheral/can/can/src/can_intr_loopback_mode_example.c +++ b/example/peripheral/can/can/src/can_intr_loopback_mode_example.c @@ -28,7 +28,6 @@ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "timers.h" #include "fcan.h" #include "fcan_os.h" #include "fcpu_info.h" @@ -79,8 +78,6 @@ static FFreeRTOSCan *os_can_ctrl_p[FCAN_NUM]; static FCanFrame send_frame[FCAN_NUM]; static FCanFrame recv_frame[FCAN_NUM]; -static u32 recv_count[FCAN_NUM] = {0}; - static FError FFreeRTOSCanSendThenRecvData(int ide); static FError FFreeRTOSCanRecvData(FCanQueueData * xReceiveStructure); static void FFreeRTOSCanDelete(void); @@ -308,7 +305,7 @@ static FError FFreeRTOSCanSendThenRecvData(int ide) { FError ret = FCAN_SUCCESS; u32 instance_id = FCAN0_ID; - u32 count = 0; + u32 count[FCAN_NUM] = {0}; BaseType_t xReturn = pdPASS; FCanQueueData xReceiveStructure; @@ -319,12 +316,12 @@ static FError FFreeRTOSCanSendThenRecvData(int ide) send_frame[instance_id].candlc = FCAN_SEND_LENGTH; if (ide == EXTEND_FRAME) { - send_frame[instance_id].canid = FCAN_SEND_EXID + count; + send_frame[instance_id].canid = FCAN_SEND_EXID + count[instance_id]; send_frame[instance_id].canid |= CAN_EFF_FLAG; } else { - send_frame[instance_id].canid = FCAN_SEND_STID + count; + send_frame[instance_id].canid = FCAN_SEND_STID + count[instance_id]; send_frame[instance_id].canid &= CAN_SFF_MASK; } @@ -339,11 +336,7 @@ static FError FFreeRTOSCanSendThenRecvData(int ide) ret = FCAN_INVAL_PARAM; return ret; } - else - { - FCAN_TEST_DEBUG("can%d send id is 0x%02x.", instance_id, send_frame[instance_id].canid); - } - count++; + count[instance_id]++; /* wait recv interrupt */ xReturn = xQueueReceive(xQueue_irq, &xReceiveStructure, TIMER_OUT); @@ -371,6 +364,7 @@ static FError FFreeRTOSCanRecvData(FCanQueueData * xReceiveStructure) FError ret = FCAN_SUCCESS; FFreeRTOSCan *os_can_p; u32 instance_id = FCAN0_ID; + static u32 recv_count[FCAN_NUM] = {0}; os_can_p = xReceiveStructure->os_can_p; instance_id = os_can_p->can_ctrl.config.instance_id; @@ -390,8 +384,8 @@ static FError FFreeRTOSCanRecvData(FCanQueueData * xReceiveStructure) return ret; } } - FCAN_TEST_DEBUG("count%d = %d: can%d recv is equal to can%d send!!!", instance_id, recv_count[instance_id], instance_id, FCAN1_ID - instance_id); recv_count[instance_id]++; + FCAN_TEST_DEBUG("count%d = %d: can%d recv is equal to can%d send!!!", instance_id, recv_count[instance_id], instance_id, FCAN1_ID - instance_id); } if (recv_count[instance_id] == FCAN_SEND_CNT) { diff --git a/example/peripheral/can/can/src/can_polled_loopback_mode_example.c b/example/peripheral/can/can/src/can_polled_loopback_mode_example.c index 65420d6f40ee4f7a99a854992cdcf20d8bfd4c3e..248756934ed71185749942b164f4936e198c9294 100644 --- a/example/peripheral/can/can/src/can_polled_loopback_mode_example.c +++ b/example/peripheral/can/can/src/can_polled_loopback_mode_example.c @@ -27,7 +27,6 @@ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "timers.h" #include "fcan.h" #include "fcan_os.h" #include "fcpu_info.h" @@ -74,8 +73,6 @@ static FFreeRTOSCan *os_can_ctrl_p[FCAN_NUM]; static FCanFrame send_frame[FCAN_NUM]; static FCanFrame recv_frame[FCAN_NUM]; -static u32 recv_count[FCAN_NUM] = {0}; - static FError FFreeRTOSCanSendThenRecvData(int ide); static FError FFreeRTOSCanRecvData(u32 instance_id); static void FFreeRTOSCanDelete(void); @@ -242,7 +239,7 @@ static FError FFreeRTOSCanSendThenRecvData(int ide) { FError ret = FCAN_SUCCESS; u32 instance_id = FCAN0_ID; - u32 count = 0; + u32 count[FCAN_NUM] = {0}; BaseType_t xReturn = pdPASS; for (int j = 0; j < FCAN_SEND_CNT; j++) @@ -252,12 +249,12 @@ static FError FFreeRTOSCanSendThenRecvData(int ide) send_frame[instance_id].candlc = FCAN_SEND_LENGTH; if (ide == EXTEND_FRAME) { - send_frame[instance_id].canid = FCAN_SEND_EXID + count; + send_frame[instance_id].canid = FCAN_SEND_EXID + count[instance_id]; send_frame[instance_id].canid |= CAN_EFF_FLAG; } else { - send_frame[instance_id].canid = FCAN_SEND_STID + count; + send_frame[instance_id].canid = FCAN_SEND_STID + count[instance_id]; send_frame[instance_id].canid &= CAN_SFF_MASK; } @@ -272,7 +269,7 @@ static FError FFreeRTOSCanSendThenRecvData(int ide) ret = FCAN_INVAL_PARAM; return ret; } - count++; + count[instance_id]++; vTaskDelay(CAN_SEND_PERIOD); /* can recv data */ @@ -291,6 +288,7 @@ return ret; static FError FFreeRTOSCanRecvData(u32 instance_id) { FError ret = FCAN_SUCCESS; + static u32 recv_count[FCAN_NUM] = {0}; instance_id = FCAN1_ID - instance_id; ret = FFreeRTOSCanRecv(os_can_ctrl_p[instance_id], &recv_frame[instance_id]); @@ -309,8 +307,8 @@ static FError FFreeRTOSCanRecvData(u32 instance_id) return ret; } } - FCAN_TEST_DEBUG("count%d = %d: can%d recv is equal to can%d send!!!", instance_id, recv_count[instance_id], instance_id, FCAN1_ID - instance_id); recv_count[instance_id]++; + FCAN_TEST_DEBUG("count%d = %d: can%d recv is equal to can%d send!!!", instance_id, recv_count[instance_id], instance_id, FCAN1_ID - instance_id); } if (recv_count[instance_id] == FCAN_SEND_CNT) { diff --git a/example/peripheral/can/canfd/README.md b/example/peripheral/can/canfd/README.md index 231bb776078df7ad8f7ba80f19bd562d88f4de74..c1d74331155def61a71531be7191d74151e61067 100644 --- a/example/peripheral/can/canfd/README.md +++ b/example/peripheral/can/canfd/README.md @@ -9,7 +9,7 @@ 使用B板进行测试,选择can0和can1回环; CANFD中断模式回环测试例程 (canfd_intr_loopback_mode_example.c) -- 初始化CAN0,CAN1基本配置,仲裁域波特率和数据域波特率配置为 1M/S+2M/S,设置滤波器,初始化中断函数 +- 初始化CAN0,CAN1基本配置,仲裁域波特率和数据域波特率配置为 1M/S+1M/S,设置滤波器,初始化中断函数 - 中断触发CAN0发送,CAN1接收,循环收发标准帧。并比对发送帧和接收帧是否相同 - 中断触发CAN1发送,CAN0接收,循环收发标准帧。并比对发送帧和接收帧是否相同 - 中断触发CAN0发送,CAN1接收,循环收发扩展帧。并比对发送帧和接收帧是否相同 @@ -25,11 +25,11 @@ CANFD轮询模式回环测试例程 (canfd_polled_loopback_mode_example.c) - 以上收发测试完成后,去初始化CAN0,CAN1,删除发送接收任务 CANFD过滤功能测试例程 (canfd_id_filter_example.c) -- 初始化CAN0,CAN1基本配置,仲裁域波特率和数据域波特率配置为 1M/S+2M/S -- 过滤模式1配置为只可接收id为0x0F的帧 +- 初始化CAN0,CAN1基本配置,仲裁域波特率和数据域波特率配置为 1M/S+4M/S +- 过滤模式1配置列表模式,只可接收id为0x0F的帧 - CAN0向CAN1发送id为(0x00~0x0F)的标准帧,CAN1成功接收id=0x0F的帧,表示成功过滤除0x0F以外的所有帧 - CAN1向CAN0发送id为(0x00~0x0F)的标准帧,CAN0成功接收id=0x0F的帧,表示成功过滤除0x0F以外的所有帧 -- 过滤模式2配置为比较较高的两位,忽略较低的两位 +- 过滤模式2配置为掩码模式,只可接收BIT3和BIT2都为1的帧(FCAN_FILTER_MODE2_MASK = 0x03) - CAN0向CAN1发送id为(0x00~0x0F)的标准帧,CAN1成功接收id=0x0C、0x0D、 0x0E、0x0F的帧 - CAN1向CAN0发送id为(0x00~0x0F)的标准帧,CAN0成功接收id=0x0C、0x0D、 0x0E、0x0F的帧 - 以上收发测试完成后,去初始化CAN0,CAN1,删除发送接收任务 @@ -38,7 +38,7 @@ CANFD过滤功能测试例程 (canfd_id_filter_example.c) 本例程需要用到 - Phytium开发板(E2000D/E2000Q) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -110,29 +110,20 @@ bootelf -p 0x90100000 - 输入```canfd intr```,启动canfd中断模式发送接收测试例子,测试完标准帧和扩展帧后自动删除任务 -![intr_stid](./figs/intr_stid.png) -...... -![intr_exid](./figs/intr_exid.png) +![canfd_intr](./figs/canfd_intr.png) - 输入```canfd polled```,启动canfd轮询模式发送接收测试例子,测试完标准帧和扩展帧后自动删除任务 -![polled_stid](./figs/polled_stid.png) -...... -![polled_exid](./figs/polled_exid.png) +![canfd_polled](./figs/canfd_polled.png) - 输入```canfd filter```,启动canfd id滤波功能测试例子,测试1只接收id=0x0F的帧,测试2接收帧id&mask(mask=0x03,结果为0表示比较,为1表示忽略),比较接收id和接收id&maskid(maskid=0x0F)的结果。全部匹配则接收否则滤除。 -滤波测试例子1 -![filter1](./figs/filter1.png) -...... -![filter1_success](./figs/filter1_success.png) -滤波测试例子2 -![filter2](./figs/filter2.png) -...... -![filter2_success](./figs/filter2_success.png) + +![canfd_filter](./figs/canfd_filter.png) ## 3. 如何解决问题 - 使用can0和can1进行回环测试时,需要将can0和can1的H和L信号线分别进行短接 +- FT2000/4和D2000和PhytiumPi不支持canfd功能的描述 ## 4. 修改历史记录 diff --git a/example/peripheral/can/canfd/figs/canfd_filter.png b/example/peripheral/can/canfd/figs/canfd_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..10338fcefb68ab8274c3cc68275db2cf225fe92d Binary files /dev/null and b/example/peripheral/can/canfd/figs/canfd_filter.png differ diff --git a/example/peripheral/can/canfd/figs/canfd_intr.png b/example/peripheral/can/canfd/figs/canfd_intr.png new file mode 100644 index 0000000000000000000000000000000000000000..a782e4ced4681ee4b41bcbdf2af0caf7d5c80b64 Binary files /dev/null and b/example/peripheral/can/canfd/figs/canfd_intr.png differ diff --git a/example/peripheral/can/canfd/figs/canfd_polled.png b/example/peripheral/can/canfd/figs/canfd_polled.png new file mode 100644 index 0000000000000000000000000000000000000000..a3c7bcaa3556cbf6e70f4331139ce330cc61c493 Binary files /dev/null and b/example/peripheral/can/canfd/figs/canfd_polled.png differ diff --git a/example/peripheral/can/canfd/inc/canfd_id_filter_example.h b/example/peripheral/can/canfd/inc/canfd_example.h similarity index 75% rename from example/peripheral/can/canfd/inc/canfd_id_filter_example.h rename to example/peripheral/can/canfd/inc/canfd_example.h index 4adc0f8d93ad4c4a50c2d6812a0536e4eb22dbcf..841e6860fe3733e5b10aa609b5577b65c675f864 100644 --- a/example/peripheral/can/canfd/inc/canfd_id_filter_example.h +++ b/example/peripheral/can/canfd/inc/canfd_example.h @@ -11,20 +11,20 @@ * See the Phytium Public License for more details. * * - * FilePath: canfd_id_filter_example.h - * Date: 2023-10-20 10:11:40 - * LastEditTime: 2023-10-20 19:00:00 + * FilePath: canfd_example.h + * Date: 2022-08-25 16:22:40 + * LastEditTime: 2022-08-26 15:40:40 * Description: This file is for task create function define * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- - * 1.0 huangjin 2023/10/17 first commit + * 1.0 huangjin 2024/04/25 first commit */ -#ifndef CANFD_ID_FILTER_EXAMPLE_H -#define CANFD_ID_FILTER_EXAMPLE_H +#ifndef CAN_EXAMPLE_H +#define CAN_EXAMPLE_H #include "portmacro.h" @@ -33,7 +33,9 @@ extern "C" { #endif -/* canfd test function */ +/* canfd test */ +BaseType_t FFreeRTOSCreateCanfdIntrTestTask(void); +BaseType_t FFreeRTOSCreateCanfdPolledTestTask(void); BaseType_t FFreeRTOSCanfdCreateFilterTestTask(void); #ifdef __cplusplus diff --git a/example/peripheral/can/canfd/inc/canfd_intr_loopback_mode_example.h b/example/peripheral/can/canfd/inc/canfd_intr_loopback_mode_example.h deleted file mode 100644 index 16e15d56cf316ebf0f861801f0443bbf09f00218..0000000000000000000000000000000000000000 --- a/example/peripheral/can/canfd/inc/canfd_intr_loopback_mode_example.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: canfd_intr_loopback_mode_example.h - * Date: 2023-10-20 10:11:40 - * LastEditTime: 2023-10-20 19:00:00 - * Description: This file is for task create function define - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - * 1.0 huangjin 2023/10/17 first commit - */ - - -#ifndef CANFD_INTR_LOOPBACK_MODE_EXAMPLE_H -#define CANFD_INTR_LOOPBACK_MODE_EXAMPLE_H - -#include "portmacro.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* canfd test function */ -BaseType_t FFreeRTOSCreateCanfdIntrTestTask(void); - - -#ifdef __cplusplus -} -#endif - -#endif // ! \ No newline at end of file diff --git a/example/peripheral/can/canfd/inc/canfd_polled_loopback_mode_example copy.h b/example/peripheral/can/canfd/inc/canfd_polled_loopback_mode_example copy.h deleted file mode 100644 index 33cbd2ece8b60dc513486a9f24c0f682acf43b9d..0000000000000000000000000000000000000000 --- a/example/peripheral/can/canfd/inc/canfd_polled_loopback_mode_example copy.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright : (C) 2022 Phytium Information Technology, Inc. - * All Rights Reserved. - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it - * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, - * either version 1.0 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the Phytium Public License for more details. - * - * - * FilePath: canfd_polled_loopback_mode_example copy.h - * Date: 2023-10-20 10:11:40 - * LastEditTime: 2023-10-20 19:00:00 - * Description: This file is for task create function define - * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - * 1.0 huangjin 2023/10/17 first commit - */ - - -#ifndef CANFD_POLLED_LOOPBACK_MODE_EXAMPLE_H -#define CANFD_POLLED_LOOPBACK_MODE_EXAMPLE_H - -#include "portmacro.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* canfd test function */ -BaseType_t FFreeRTOSCreateCanfdPolledTestTask(void); - -#ifdef __cplusplus -} -#endif - -#endif // ! \ No newline at end of file diff --git a/example/peripheral/can/canfd/main.c b/example/peripheral/can/canfd/main.c index 156a904fb6a09cc9c94a866063b61a83ec51c01a..a4304c9c017a89acb26fe34a7c0e47e1f6106466 100644 --- a/example/peripheral/can/canfd/main.c +++ b/example/peripheral/can/canfd/main.c @@ -20,20 +20,50 @@ * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 huangjin 2023/10/20 first commit + * 2.0 huangjin 2024/04/25 add no letter shell mode, adapt to auto-test system */ +#include +#include "FreeRTOS.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include -#include "canfd_intr_loopback_mode_example.h" -#include "canfd_polled_loopback_mode_example copy.h" -#include "canfd_id_filter_example.h" +#else +#include "task.h" +#include "canfd_example.h" + +#define CANFD_EXAMPLE_TASK_PRIORITY 2 + +void CanfdExampleTaskEntry(void *pvParameters) +{ + /* example functions */ + FFreeRTOSCreateCanfdIntrTestTask(); + FFreeRTOSCreateCanfdPolledTestTask(); + FFreeRTOSCanfdCreateFilterTestTask(); + + /* end flag */ + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif + int main(void) { - BaseType_t ret; + BaseType_t ret = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - ret = LSUserShellTask() ; +#ifdef CONFIG_USE_LETTER_SHELL + ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)CanfdExampleTaskEntry, /* 任务入口函数 */ + (const char *)"CanfdExampleTaskEntry",/* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)CANFD_EXAMPLE_TASK_PRIORITY, /* 任务的优先级 */ + NULL); +#endif if (ret != pdPASS) { goto FAIL_EXIT; @@ -43,6 +73,6 @@ int main(void) while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("failed 0x%x. \r\n", ret); + printf("CANFD example failed in main.c, the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/peripheral/can/canfd/src/canfd_id_filter_example.c b/example/peripheral/can/canfd/src/canfd_id_filter_example.c index 10d75629e36f3372cb9150ff1db28d87f49815e0..b7effe7d384109562886011ab8bb1029b779b786 100644 --- a/example/peripheral/can/canfd/src/canfd_id_filter_example.c +++ b/example/peripheral/can/canfd/src/canfd_id_filter_example.c @@ -20,6 +20,7 @@ * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 huangjin 2023/10/7 first release + * 2.0 huangjin 2024/04/25 add no letter shell mode, adapt to auto-test system */ /***************************** Include Files *********************************/ @@ -28,7 +29,6 @@ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "timers.h" #include "fcan.h" #include "fcan_os.h" #include "fcpu_info.h" @@ -43,38 +43,50 @@ #define FCAN_TEST_WARN(format, ...) FT_DEBUG_PRINT_W(FCAN_TEST_DEBUG_TAG, format, ##__VA_ARGS__) #define FCAN_TEST_ERROR(format, ...) FT_DEBUG_PRINT_E(FCAN_TEST_DEBUG_TAG, format, ##__VA_ARGS__) -/* canfd frame config */ -#define FCAN_SEND_LENGTH 16//canfd帧长度 -#define FCAN_FILTER_ID 0x02//滤波使用的id - -/* canfd send period */ -#define CAN_SEND_PERIOD ( pdMS_TO_TICKS( 100UL )) +enum +{ + CANFD_TEST_SUCCESS = 0, /*Canfd intr loopback mode test success*/ + CANFD_INIT_FAILURE = 1, /*Canfd init step failure */ + CANFD_SEND_FAILURE = 2, /*Canfd send step failure */ + CANFD_RECV_FAILURE = 3, /*Canfd recv step failure */ + CANFD_DATA_FAILURE = 4, /*Canfd data is not equal */ + CANFD_UNKNOWN_STATE = 5, /*Canfd example unknown state */ +}; + +/* can frame config */ +#define CANFD_ENABLE TRUE +#define CAN_FILTER_MODE_1 1 +#define CAN_FILTER_MODE_2 2 +#define FCAN_SEND_LENGTH 16 +#define FCAN_FILTER_MODE1_ID 0x0F +#define FCAN_FILTER_MODE1_MASK 0x00 +#define FCAN_FILTER_MODE2_ID 0x0C +#define FCAN_FILTER_MODE2_MASK 0x03 +#define FCAN_FILTER_MODE2_CNT 4 +#define TIMER_OUT (pdMS_TO_TICKS(10000UL)) +#define RECV_TIMER_OUT (pdMS_TO_TICKS(100UL)) +#define CAN_FILTER_TASK_PRIORITY 3 #define ARB_BAUD_RATE 1000000 -#define DATA_BAUD_RATE 2000000 +#define DATA_BAUD_RATE 4000000 /**************************** Type Definitions *******************************/ typedef struct { - u32 count; FFreeRTOSCan *os_can_p; } FCanQueueData; /************************** Variable Definitions *****************************/ /* Declare a variable of type QueueHandle_t. This is used to store the queue that is accessed by all three tasks. */ -static QueueHandle_t xQueue; - -static xSemaphoreHandle test_semaphore; - -static xTaskHandle send_handle; -static xTaskHandle recv_handle; +static QueueHandle_t xQueue_irq; +static QueueHandle_t xQueue_task; static FFreeRTOSCan *os_can_ctrl_p[FCAN_NUM]; static FCanFrame send_frame[FCAN_NUM]; static FCanFrame recv_frame[FCAN_NUM]; -static void FFreeRTOSCanfdSendTask(void *pvParameters); -static void FFreeRTOSCanfdRecvTask(void *pvParameters); +static FError FFreeRTOSCanfdSendThenRecvData(int mode); +static FError FFreeRTOSCanfdRecvData(int mode, FCanQueueData *xReceiveStructure); static void FFreeRTOSCanDelete(void); /***************** Macros (Inline Functions) Definitions *********************/ @@ -82,12 +94,6 @@ static void FFreeRTOSCanDelete(void); /************************** Function Prototypes ******************************/ /************************** Function *****************************************/ -static void FCanTxIrqCallback(void *args) -{ - FFreeRTOSCan *os_can_p = (FFreeRTOSCan *)args; - FCAN_TEST_DEBUG("Can%d irq send frame is ok.", os_can_p->can_ctrl.config.instance_id); -} - static void FCanRxIrqCallback(void *args) { FFreeRTOSCan *os_can_p = (FFreeRTOSCan *)args; @@ -98,7 +104,7 @@ static void FCanRxIrqCallback(void *args) portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - xQueueSendToBackFromISR(xQueue, &xSendStructure, &xHigherPriorityTaskWoken); + xQueueSendToBackFromISR(xQueue_irq, &xSendStructure, &xHigherPriorityTaskWoken); /* never call taskYIELD() form ISR! */ portYIELD_FROM_ISR(xHigherPriorityTaskWoken); @@ -111,16 +117,6 @@ static FError FFreeRTOSCanIntrSet(FFreeRTOSCan *os_can_p) FCanIntrEventConfig intr_event; memset(&intr_event, 0, sizeof(intr_event)); - intr_event.type = FCAN_INTR_EVENT_SEND; - intr_event.handler = FCanTxIrqCallback; - intr_event.param = (void *)os_can_p; - ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_INTR_SET, &intr_event); - if (FCAN_SUCCESS != ret) - { - FCAN_TEST_ERROR("FFreeRTOSCanControl FCAN_INTR_EVENT_SEND failed."); - return ret; - } - intr_event.type = FCAN_INTR_EVENT_RECV; intr_event.handler = FCanRxIrqCallback; intr_event.param = (void *)os_can_p; @@ -142,7 +138,6 @@ static FError FFreeRTOSCanIntrSet(FFreeRTOSCan *os_can_p) return ret; } - static FError FFreeRTOSCanBaudrateSet(FFreeRTOSCan *os_can_p) { FError ret = FCAN_SUCCESS; @@ -175,20 +170,19 @@ static FError FFreeRTOSCanBaudrateSet(FFreeRTOSCan *os_can_p) return ret; } - -static FError FFreeRTOSCanIdMaskSet(FFreeRTOSCan *os_can_p, void *pvParameters) +static FError FFreeRTOSCanIdMaskSet(FFreeRTOSCan *os_can_p, int mode) { FError ret = FCAN_SUCCESS; - if ( ((int)(uintptr)pvParameters) == 1 ) + if ( mode == CAN_FILTER_MODE_1 ) { FCanIdMaskConfig id_mask; memset(&id_mask, 0, sizeof(id_mask)); for (int i = 0; i < FCAN_ACC_ID_REG_NUM; i++) { id_mask.filter_index = i; - id_mask.id = 0x0F;//只接收id的消息 - id_mask.mask = 0x00;//掩码 FCAN_ACC_IDN_MASK 对应位为 1:则忽略 0:则比较 + id_mask.id = FCAN_FILTER_MODE1_ID;//只接收id的消息 + id_mask.mask = FCAN_FILTER_MODE1_MASK;//掩码 FCAN_ACC_IDN_MASK 对应位为 1:则忽略 0:则比较 ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_ID_MASK_SET, &id_mask); if (FCAN_SUCCESS != ret) { @@ -197,15 +191,15 @@ static FError FFreeRTOSCanIdMaskSet(FFreeRTOSCan *os_can_p, void *pvParameters) } } } - else if ( ((int)(uintptr)pvParameters) == 2 ) + else if ( mode == CAN_FILTER_MODE_2 ) { FCanIdMaskConfig id_mask; memset(&id_mask, 0, sizeof(id_mask)); for (int i = 0; i < FCAN_ACC_ID_REG_NUM; i++) { id_mask.filter_index = i; - id_mask.id = 0x0C;//(canid&maskid)与canid比较 - id_mask.mask = 0x03;//0011 比较高两位,忽略低两位 + id_mask.id = FCAN_FILTER_MODE2_ID;//(canid&maskid)与canid比较 + id_mask.mask = FCAN_FILTER_MODE2_MASK;//0011 比较高两位,忽略低两位 ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_ID_MASK_SET, &id_mask); if (FCAN_SUCCESS != ret) { @@ -218,246 +212,298 @@ static FError FFreeRTOSCanIdMaskSet(FFreeRTOSCan *os_can_p, void *pvParameters) return ret; } -static void FFreeRTOSCanInitTask(void *pvParameters) +static FError CanInit(int ide) { - FError ret = FCAN_SUCCESS; - BaseType_t xReturn = pdPASS; u32 instance_id = FCAN0_ID; + FError init_ret = FCAN_FAILURE; u32 tran_mode = FCAN_PROBE_NORMAL_MODE; - boolean use_canfd = TRUE; - - /* The queue is created to hold a maximum of 32 structures of type xData. */ - xQueue = xQueueCreate(32, sizeof(FCanQueueData)); - if (xQueue == NULL) - { - printf("FFreeRTOSCanCreateFilterTestTask FCanQueueData create failed.\r\n"); - } /*init iomux*/ FIOMuxInit(); - for (instance_id = FCAN0_ID; instance_id < FCAN_NUM; instance_id++) + for (instance_id = FCAN0_ID; instance_id <= FCAN1_ID; instance_id++) { FIOPadSetCanMux(instance_id); - - /* init canfd controller */ + + /* init can controller */ os_can_ctrl_p[instance_id] = FFreeRTOSCanInit(instance_id); if (os_can_ctrl_p[instance_id] == NULL) { - printf("FFreeRTOSCanInit %d failed!!!\r\n", instance_id); - goto canfd_init_exit; + FCAN_TEST_ERROR("FFreeRTOSCanInit %d failed!!!", instance_id); + return init_ret; } /* enable canfd */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_FD_ENABLE, (void *)use_canfd); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_FD_ENABLE, (void *)CANFD_ENABLE); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_FD_ENABLE failed."); - goto canfd_init_exit; - } + return init_ret; + } - /* set canfd baudrate */ - ret = FFreeRTOSCanBaudrateSet(os_can_ctrl_p[instance_id]); - if (FCAN_SUCCESS != ret) + /* set can baudrate */ + init_ret = FFreeRTOSCanBaudrateSet(os_can_ctrl_p[instance_id]); + if (FCAN_SUCCESS != init_ret) { - printf("FFreeRTOSCanInit FFreeRTOSCanBaudrateSet failed!!!\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("FFreeRTOSCanInit FFreeRTOSCanBaudrateSet failed!!!"); + return init_ret; } - /* set canfd id mask */ - ret = FFreeRTOSCanIdMaskSet(os_can_ctrl_p[instance_id], pvParameters); - if (FCAN_SUCCESS != ret) + /* set can id mask */ + init_ret = FFreeRTOSCanIdMaskSet(os_can_ctrl_p[instance_id], ide); + if (FCAN_SUCCESS != init_ret) { - printf("FFreeRTOSCanInit FFreeRTOSCanIdMaskSet failed!!!\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("FFreeRTOSCanInit FFreeRTOSCanIdMaskSet failed!!!"); + return init_ret; } /* Identifier mask enable */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ID_MASK_ENABLE, NULL); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ID_MASK_ENABLE, NULL); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ID_MASK_ENABLE failed."); - goto canfd_init_exit; + return init_ret; } - /* init canfd interrupt handler */ - ret = FFreeRTOSCanIntrSet(os_can_ctrl_p[instance_id]); - if (FCAN_SUCCESS != ret) + /* init can interrupt handler */ + init_ret = FFreeRTOSCanIntrSet(os_can_ctrl_p[instance_id]); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanInit FFreeRTOSCanIntrSet failed!!!"); - goto canfd_init_exit; + return init_ret; } - /* set canfd transfer mode */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_MODE_SET, &tran_mode); - if (FCAN_SUCCESS != ret) + /* set can transfer mode */ + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_MODE_SET, &tran_mode); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_MODE_SET failed."); - goto canfd_init_exit; + return init_ret; } - /* enable canfd transfer */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ENABLE, NULL); - if (FCAN_SUCCESS != ret) + /* enable can transfer */ + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ENABLE, NULL); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ENABLE failed."); - goto canfd_init_exit; + return init_ret; } - } - printf("\r\nFFreeRTOSCanInitTask execute success !!!\r\n"); + return init_ret; +} - if ( ((int)(uintptr)pvParameters) == 1 ) - { - printf("\r\nTest Example 1: Only frames with id 0x0F are received !!!\r\n");//测试例子1 - } - else if ( ((int)(uintptr)pvParameters) == 2 ) +static void FFreeRTOSCanfdFilterTask(void *pvParameters) +{ + FError ret = FCAN_SUCCESS; + int task_res = 0; + int mode = (int)(uintptr)pvParameters; + + /* The queue is created to hold a maximum of 32 structures of type xData. */ + xQueue_irq = xQueueCreate(32, sizeof(FCanQueueData)); + if (xQueue_irq == NULL) { - printf("\r\nTest Example 2: Compare the higher two bit and ignore the lower two bit !!!\r\n");//测试例子2 + FCAN_TEST_ERROR("xQueue_irq create failed."); } - /* canfd send task */ - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdSendTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanfdSendTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 5, /* 任务的优先级 */ - (TaskHandle_t *)&send_handle); /* 任务控制 */ - if (xReturn != pdPASS) + /* init can controller */ + ret = CanInit(mode); + if (CANFD_TEST_SUCCESS != ret) { - printf("Create FFreeRTOSCanfdSendTask failed.\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("Can init failed."); + task_res = CANFD_INIT_FAILURE; + goto can_test_exit; } - /* canfd recv task */ - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdRecvTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanfdRecvTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 5, /* 任务的优先级 */ - (TaskHandle_t *)&recv_handle); /* 任务控制 */ - if (xReturn != pdPASS) + /* can send data */ + ret = FFreeRTOSCanfdSendThenRecvData(mode); + if (CANFD_TEST_SUCCESS != ret) { - printf("Create FFreeRTOSCanfdRecvTask failed.\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("Canfd send then recv data failed."); + task_res = CANFD_DATA_FAILURE; + goto can_test_exit; } -canfd_init_exit: +can_test_exit: + FFreeRTOSCanDelete(); + xQueueSend(xQueue_task, &task_res, 0); vTaskDelete(NULL); } -static void FFreeRTOSCanfdSendTask(void *pvParameters) +static FError FFreeRTOSCanfdSendThenRecvData(int mode) { FError ret = FCAN_SUCCESS; - u32 instance_id = FCAN0_ID; u32 count[FCAN_NUM] = {0}; - int i = 0; - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) - { - printf("\r\ncanfd send task running.\r\n"); - for (instance_id = FCAN0_ID; instance_id <= FCAN1_ID; instance_id++) + BaseType_t xReturn = pdPASS; + FCanQueueData xReceiveStructure; + + for (u32 instance_id = FCAN0_ID; instance_id <= FCAN1_ID; instance_id++) + { + //canfd id递增发送 + for (u32 id = 0x00; id <= 0x0F; id++) { - //canfd id递增发送 - for (u32 id = 0x00; id <= 0x0F; id++) + send_frame[instance_id].canid = id; + send_frame[instance_id].canid &= CAN_EFF_MASK; + send_frame[instance_id].candlc = FCAN_SEND_LENGTH; + for (int i = 0; i < send_frame[instance_id].candlc; i++) { - send_frame[instance_id].canid = id;//帧id - send_frame[instance_id].canid &= CAN_EFF_MASK;//检验帧有效性 CAN_SFF_MASK(标准帧) CAN_EFF_MASK(扩展帧) - send_frame[instance_id].candlc = FCAN_SEND_LENGTH;//帧长度 - for (i = 0; i < send_frame[instance_id].candlc; i++) - { - send_frame[instance_id].data[i] = i + (instance_id << 4); - } - ret = FFreeRTOSCanSend(os_can_ctrl_p[instance_id], &send_frame[instance_id]); - if (ret != FCAN_SUCCESS) + send_frame[instance_id].data[i] = i + (instance_id << 4); + } + ret = FFreeRTOSCanSend(os_can_ctrl_p[instance_id], &send_frame[instance_id]); + if (ret != FCAN_SUCCESS) + { + FCAN_TEST_ERROR("canfd%d send failed.", instance_id); + ret = FCAN_INVAL_PARAM; + return ret; + } + count[instance_id]++; + + /* wait recv interrupt */ + xReturn = xQueueReceive(xQueue_irq, &xReceiveStructure, RECV_TIMER_OUT); + if (xReturn == pdPASS) + { + /* can recv data */ + ret = FFreeRTOSCanfdRecvData(mode, &xReceiveStructure); + if (CANFD_TEST_SUCCESS != ret) { - printf("canfd%d send failed.\n", instance_id); + FCAN_TEST_ERROR("Canfd recv data failed."); + return ret; } - count[instance_id]++; - printf("\r\ncanfd%d send frame id is: 0x%02x\r\n", instance_id, send_frame[instance_id].canid); - vTaskDelay(CAN_SEND_PERIOD); + } + else + { + continue; } } - vTaskDelete(NULL); } + + return ret; } -static void FFreeRTOSCanfdRecvTask(void *pvParameters) +static FError FFreeRTOSCanfdRecvData(int mode, FCanQueueData *xReceiveStructure) { FError ret = FCAN_SUCCESS; - u32 count[FCAN_NUM] = {0}; - int i = 0; - static FCanQueueData xReceiveStructure; FFreeRTOSCan *os_can_p; u32 instance_id = FCAN0_ID; - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) + static u32 recv_count[FCAN_NUM] = {0}; + + os_can_p = xReceiveStructure->os_can_p; + instance_id = os_can_p->can_ctrl.config.instance_id; + ret = FFreeRTOSCanRecv(os_can_p, &recv_frame[instance_id]); + if (FCAN_SUCCESS == ret) { - /* wait recv interrupt give semphore */ - xQueueReceive(xQueue, &xReceiveStructure, portMAX_DELAY); - os_can_p = xReceiveStructure.os_can_p; - instance_id = os_can_p->can_ctrl.config.instance_id; - ret = FFreeRTOSCanRecv(os_can_p, &recv_frame[instance_id]); - if (FCAN_SUCCESS == ret) + FCAN_TEST_DEBUG("canfd%d recv id is 0x%02x.", instance_id, recv_frame[instance_id].canid); + if (recv_frame[instance_id].canid == send_frame[FCAN1_ID - instance_id].canid) { - printf("canfd%d recv id is 0x%02x.\r\n", instance_id, recv_frame[instance_id].canid); - for (i = 0; i < recv_frame[instance_id].candlc; i++) + for (int i = 0; i < recv_frame[instance_id].candlc; i++) { if (recv_frame[instance_id].data[i] != send_frame[FCAN1_ID - instance_id].data[i]) { - FCAN_TEST_ERROR("\ncount=%d: canfd%d recv is not equal to canfd%d send!!!\r\n", count[instance_id], instance_id, FCAN1_ID - instance_id); + FCAN_TEST_ERROR("count=%d: canfd%d recv is not equal to canfd%d send!!!", recv_count[instance_id], instance_id, FCAN1_ID - instance_id); + ret = CANFD_DATA_FAILURE; + return ret; } } - count[instance_id]++; - - /* 被过滤的帧,进不到此函数 */ - if ( recv_frame[instance_id].canid != send_frame[FCAN1_ID - instance_id].canid) - { - printf("The frame id:0x%02x was filtered successfully.\r\n", send_frame[FCAN1_ID - instance_id].canid); - } - else + } + FCAN_TEST_DEBUG("The frame id:0x%02x was receved successfully.", recv_frame[instance_id].canid); + + if ( (mode == CAN_FILTER_MODE_1) && (recv_frame[instance_id].canid == FCAN_FILTER_MODE1_ID) ) + { + printf("canfd%d -> canfd%d: Filter mode1 test completed.\r\n", FCAN1_ID - instance_id, instance_id); + return ret; + } + else if ( (mode == CAN_FILTER_MODE_2) && ((recv_frame[instance_id].canid & FCAN_FILTER_MODE2_ID) == FCAN_FILTER_MODE2_ID) ) + { + recv_count[instance_id]++; + if ( recv_count[instance_id] == FCAN_FILTER_MODE2_CNT ) { - printf("The frame id:0x%02x was receved successfully.\r\n", recv_frame[instance_id].canid); + printf("canfd%d -> canfd%d: Filter mode2 test completed.\r\n", FCAN1_ID - instance_id, instance_id); + recv_count[instance_id] = 0; + return ret; } } - if ((instance_id == 0) && (recv_frame[instance_id].canid == 0x0F)) + else { - FFreeRTOSCanDelete(); + /* 过滤失败 */ + FCAN_TEST_ERROR("canfd%d recv id 0x%02x should not be received!!!", instance_id, recv_frame[instance_id].canid); + ret = CANFD_DATA_FAILURE; + return ret; } } + + return ret; } /* function1,2 of canfd id filter example */ BaseType_t FFreeRTOSCanfdCreateFilterTestTask(void) { + int task_res = CANFD_UNKNOWN_STATE; BaseType_t xReturn = pdPASS; - BaseType_t timer_started = pdPASS; - test_semaphore = xSemaphoreCreateBinary(); - if (test_semaphore != NULL) + xQueue_task = xQueueCreate(1, sizeof(int)); + if (xQueue_task == NULL) { - xSemaphoreGive(test_semaphore); + FCAN_TEST_ERROR("xQueue_task create failed."); + goto exit; } /* canfd filter test1 task */ - xSemaphoreTake(test_semaphore, portMAX_DELAY); - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanInitTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanInitTask",/* 任务名字 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdFilterTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSCanfdFilterMode1Task",/* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ - (void *)1,/* 任务入口函数参数 */ - (UBaseType_t)1, /* 任务的优先级 */ + (void *)CAN_FILTER_MODE_1,/* 任务入口函数参数 */ + (UBaseType_t)CAN_FILTER_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xTaskCreate FFreeRTOSCanfdFilterMode1Task failed."); + goto exit; + } + + xReturn = xQueueReceive(xQueue_task, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xQueue_task receive timeout."); + goto exit; + } /* canfd filter test2 task */ - xSemaphoreTake(test_semaphore, portMAX_DELAY); - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanInitTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanInit2Task",/* 任务名字 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdFilterTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSCanfdFilterMode2Task",/* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ - (void *)2,/* 任务入口函数参数 */ - (UBaseType_t)1, /* 任务的优先级 */ + (void *)CAN_FILTER_MODE_2,/* 任务入口函数参数 */ + (UBaseType_t)CAN_FILTER_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xTaskCreate FFreeRTOSCanfdFilterMode2Task failed."); + goto exit; + } + + xReturn = xQueueReceive(xQueue_task, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xQueue_task receive timeout."); + goto exit; + } +exit: + if (xQueue_task != NULL) + { + vQueueDelete(xQueue_task); + } + + if (task_res != CANFD_TEST_SUCCESS) + { + printf("%s@%d: Canfd Filter mode example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return pdFAIL; + } + else + { + printf("%s@%d: Canfd Filter mode example [success].\r\n", __func__, __LINE__); + return pdPASS; + } + return xReturn; } @@ -471,14 +517,5 @@ static void FFreeRTOSCanDelete(void) FIOMuxDeInit(); /* delete queue */ - vQueueDelete(xQueue); - - xSemaphoreGive(test_semaphore); - - if (recv_handle) - { - vPrintf("\r\nDelete FFreeRTOSCanRecvTask success.\r\n"); - vPrintf("\r\nDelete FFreeRTOSCanSendTask success.\r\n"); - vTaskDelete(recv_handle); - } + vQueueDelete(xQueue_irq); } diff --git a/example/peripheral/can/canfd/src/canfd_intr_loopback_mode_example.c b/example/peripheral/can/canfd/src/canfd_intr_loopback_mode_example.c index f104f62c4d37393fd0a4200c0afa1e0b676bd972..e00650cad2d9a568dcb1b81600007179c635707d 100644 --- a/example/peripheral/can/canfd/src/canfd_intr_loopback_mode_example.c +++ b/example/peripheral/can/canfd/src/canfd_intr_loopback_mode_example.c @@ -14,19 +14,19 @@ * FilePath: canfd_intr_loopback_mode_example.c * Date: 2023-10-20 11:32:48 * LastEditTime: 2023-10-20 11:32:48 - * Description: This file is for CAN task implementations + * Description: This file is for canfd intr loopback mode example task implementations * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- - * 1.0 huangjin 2023/10/7 first commit + * 1.0 huangjin 2023/10/7 first commit + * 2.0 huangjin 2024/04/25 add no letter shell mode, adapt to auto-test system */ #include #include #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "timers.h" #include "fcan.h" #include "fcan_os.h" #include "fcpu_info.h" @@ -40,49 +40,47 @@ #define FCAN_TEST_WARN(format, ...) FT_DEBUG_PRINT_W(FCAN_TEST_DEBUG_TAG, format, ##__VA_ARGS__) #define FCAN_TEST_ERROR(format, ...) FT_DEBUG_PRINT_E(FCAN_TEST_DEBUG_TAG, format, ##__VA_ARGS__) +enum +{ + CANFD_TEST_SUCCESS = 0, /*Canfd intr loopback mode test success*/ + CANFD_INIT_FAILURE = 1, /*Canfd init step failure */ + CANFD_SEND_FAILURE = 2, /*Canfd send step failure */ + CANFD_RECV_FAILURE = 3, /*Canfd recv step failure */ + CANFD_DATA_FAILURE = 4, /*Canfd data is not equal */ + CANFD_UNKNOWN_STATE = 5, /*Canfd example unknown state */ +}; + /* canfd frame config */ +#define CANFD_ENABLE TRUE #define FCAN_SEND_STID 0x000007FDU #define FCAN_SEND_EXID 0x1FFFFFFDU #define FCAN_SEND_LENGTH 16 -#define FCAN_SEND_STID_MAX 0x000007FFU -#define FCAN_SEND_EXID_MAX 0x1FFFFFFFU - -/* canfd send period */ -#define CAN_SEND_PERIOD ( pdMS_TO_TICKS( 100UL )) +#define FCANFD_SEND_CNT 3 +#define TIMER_OUT ( pdMS_TO_TICKS( 3000UL ) ) +#define CANFD_INTR_TASK_PRIORITY 3 /* canfd baudrate */ #define ARB_BAUD_RATE 1000000 -#define DATA_BAUD_RATE 2000000 +#define DATA_BAUD_RATE 1000000 typedef struct { - u32 count; FFreeRTOSCan *os_can_p; } FCanQueueData; /* Declare a variable of type QueueHandle_t. This is used to store the queue that is accessed by all three tasks. */ -static QueueHandle_t xQueue; - -static xSemaphoreHandle test_semaphore; - -static xTaskHandle send_handle; -static xTaskHandle recv_handle; +static QueueHandle_t xQueue_irq; +static QueueHandle_t xQueue_task; static FFreeRTOSCan *os_can_ctrl_p[FCAN_NUM]; static FCanFrame send_frame[FCAN_NUM]; static FCanFrame recv_frame[FCAN_NUM]; -static void FFreeRTOSCanfdSendTask(void *pvParameters); -static void FFreeRTOSCanfdRecvTask(void *pvParameters); +static FError FFreeRTOSCanfdSendThenRecvData(int ide); +static FError FFreeRTOSCanfdRecvData(FCanQueueData *xReceiveStructure); static void FFreeRTOSCanDelete(void); -static void FCanTxIrqCallback(void *args) -{ - FFreeRTOSCan *os_can_p = (FFreeRTOSCan *)args; - FCAN_TEST_DEBUG("Can%d irq send frame is ok.", os_can_p->can_ctrl.config.instance_id); -} - static void FCanRxIrqCallback(void *args) { FFreeRTOSCan *os_can_p = (FFreeRTOSCan *)args; @@ -93,7 +91,7 @@ static void FCanRxIrqCallback(void *args) portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - xQueueSendToBackFromISR(xQueue, &xSendStructure, &xHigherPriorityTaskWoken); + xQueueSendToBackFromISR(xQueue_irq, &xSendStructure, &xHigherPriorityTaskWoken); /* never call taskYIELD() form ISR! */ portYIELD_FROM_ISR(xHigherPriorityTaskWoken); @@ -102,20 +100,9 @@ static void FCanRxIrqCallback(void *args) static FError FFreeRTOSCanIntrSet(FFreeRTOSCan *os_can_p) { FError ret = FCAN_SUCCESS; - FCanIntrEventConfig intr_event; memset(&intr_event, 0, sizeof(intr_event)); - intr_event.type = FCAN_INTR_EVENT_SEND; - intr_event.handler = FCanTxIrqCallback; - intr_event.param = (void *)os_can_p; - ret = FFreeRTOSCanControl(os_can_p, FREERTOS_CAN_CTRL_INTR_SET, &intr_event); - if (FCAN_SUCCESS != ret) - { - FCAN_TEST_ERROR("FFreeRTOSCanControl FCAN_INTR_EVENT_SEND failed."); - return ret; - } - intr_event.type = FCAN_INTR_EVENT_RECV; intr_event.handler = FCanRxIrqCallback; intr_event.param = (void *)os_can_p; @@ -137,7 +124,6 @@ static FError FFreeRTOSCanIntrSet(FFreeRTOSCan *os_can_p) return ret; } - static FError FFreeRTOSCanBaudrateSet(FFreeRTOSCan *os_can_p) { FError ret = FCAN_SUCCESS; @@ -170,7 +156,6 @@ static FError FFreeRTOSCanBaudrateSet(FFreeRTOSCan *os_can_p) return ret; } - static FError FFreeRTOSCanIdMaskSet(FFreeRTOSCan *os_can_p, int frame_type) { FError ret = FCAN_SUCCESS; @@ -197,252 +182,295 @@ static FError FFreeRTOSCanIdMaskSet(FFreeRTOSCan *os_can_p, int frame_type) return ret; } -static void FFreeRTOSCanInitTask(void *pvParameters) +static FError CanInit(int ide) { - FError ret = FCAN_SUCCESS; - BaseType_t xReturn = pdPASS; u32 instance_id = FCAN0_ID; + FError init_ret = FCAN_FAILURE; u32 tran_mode = FCAN_PROBE_NORMAL_MODE; - /* The queue is created to hold a maximum of 32 structures of type xData. */ - xQueue = xQueueCreate(32, sizeof(FCanQueueData)); - if (xQueue == NULL) - { - printf("FFreeRTOSCreateCanfdIntrTestTask FCanQueueData create failed.\r\n"); - } - /*init iomux*/ FIOMuxInit(); - for (instance_id = FCAN0_ID; instance_id < FCAN_NUM; instance_id++) + for (instance_id = FCAN0_ID; instance_id <= FCAN1_ID; instance_id++) { FIOPadSetCanMux(instance_id); - - /* init canfd controller */ + + /* init can controller */ os_can_ctrl_p[instance_id] = FFreeRTOSCanInit(instance_id); if (os_can_ctrl_p[instance_id] == NULL) { - printf("FFreeRTOSCanInit %d failed!!!\r\n", instance_id); - goto canfd_init_exit; + FCAN_TEST_ERROR("FFreeRTOSCanInit %d failed!!!", instance_id); + return init_ret; } /* enable canfd */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_FD_ENABLE, (void *)1); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_FD_ENABLE, (void *)CANFD_ENABLE); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_FD_ENABLE failed."); - goto canfd_init_exit; + return init_ret; } /* set canfd baudrate */ - ret = FFreeRTOSCanBaudrateSet(os_can_ctrl_p[instance_id]); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanBaudrateSet(os_can_ctrl_p[instance_id]); + if (FCAN_SUCCESS != init_ret) { - printf("FFreeRTOSCanInit FFreeRTOSCanBaudrateSet failed!!!\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("FFreeRTOSCanInit FFreeRTOSCanBaudrateSet failed!!!"); + return init_ret; } /* set canfd id mask */ - ret = FFreeRTOSCanIdMaskSet(os_can_ctrl_p[instance_id], ((int)(uintptr)pvParameters)); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanIdMaskSet(os_can_ctrl_p[instance_id], ide); + if (FCAN_SUCCESS != init_ret) { - printf("FFreeRTOSCanInit FFreeRTOSCanIdMaskSet failed!!!\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("FFreeRTOSCanInit FFreeRTOSCanIdMaskSet failed!!!"); + return init_ret; } /* Identifier mask enable */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ID_MASK_ENABLE, NULL); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ID_MASK_ENABLE, NULL); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ID_MASK_ENABLE failed."); - goto canfd_init_exit; + return init_ret; } /* init canfd interrupt handler */ - ret = FFreeRTOSCanIntrSet(os_can_ctrl_p[instance_id]); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanIntrSet(os_can_ctrl_p[instance_id]); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanInit FFreeRTOSCanIntrSet failed!!!"); - goto canfd_init_exit; + return init_ret; } - /* set canfd transfer mode */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_MODE_SET, &tran_mode); - if (FCAN_SUCCESS != ret) + /* set can transfer mode */ + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_MODE_SET, &tran_mode); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_MODE_SET failed."); - goto canfd_init_exit; + return init_ret; } /* enable canfd transfer */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ENABLE, NULL); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ENABLE, NULL); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ENABLE failed."); - goto canfd_init_exit; + return init_ret; } - } - printf("FFreeRTOSCanInitTask execute success !!!\r\n"); + return init_ret; +} + +static void FFreeRTOSCanfdIntrTask(void *pvParameters) +{ + FError ret = FCAN_SUCCESS; + int task_res = CANFD_TEST_SUCCESS; + int ide = (int)(uintptr)pvParameters; - if ( ((int)(uintptr)pvParameters) == 0 ) + /* The queue is created to hold a maximum of 32 structures of type xData. */ + xQueue_irq = xQueueCreate(32, sizeof(FCanQueueData)); + if (xQueue_irq == NULL) { - printf("Standard frame test example!!!\r\n"); + FCAN_TEST_ERROR("xQueue_irq create failed."); } - else if ( ((int)(uintptr)pvParameters) == 1 ) + + /* init can controller */ + ret = CanInit(ide); + if (CANFD_TEST_SUCCESS != ret) { - printf("Extended frame test example!!!\r\n"); + FCAN_TEST_ERROR("Can init failed."); + task_res = CANFD_INIT_FAILURE; + goto canfd_test_exit; } - /* canfd send task */ - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdSendTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanfdSendTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - pvParameters,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 5, /* 任务的优先级 */ - (TaskHandle_t *)&send_handle); /* 任务控制 */ - if (xReturn != pdPASS) + /* canfd send data then recv data */ + ret = FFreeRTOSCanfdSendThenRecvData(ide); + if (CANFD_TEST_SUCCESS != ret) { - printf("Create FFreeRTOSCanfdSendTask failed.\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("Canfd send then recv data failed."); + task_res = CANFD_DATA_FAILURE; + goto canfd_test_exit; } - /* canfd recv task */ - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdRecvTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanfdRecvTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 5, /* 任务的优先级 */ - (TaskHandle_t *)&recv_handle); /* 任务控制 */ - if (xReturn != pdPASS) +canfd_test_exit: + xQueueSend(xQueue_task, &task_res, 0); + if (task_res != CANFD_INIT_FAILURE) { - printf("Create FFreeRTOSCanfdRecvTask failed.\r\n"); - goto canfd_init_exit; + FFreeRTOSCanDelete(); } - -canfd_init_exit: vTaskDelete(NULL); } -static void FFreeRTOSCanfdSendTask(void *pvParameters) +static FError FFreeRTOSCanfdSendThenRecvData(int ide) { FError ret = FCAN_SUCCESS; - u32 instance_id = FCAN0_ID; u32 count[FCAN_NUM] = {0}; - u32 send_max_id; - int i = 0; - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) + BaseType_t xReturn = pdPASS; + FCanQueueData xReceiveStructure; + + for (int j = 0; j < FCANFD_SEND_CNT; j++) { - printf("\r\ncanfd send task running.\r\n"); - for (instance_id = FCAN0_ID; instance_id <= FCAN1_ID; instance_id++) + for (u32 instance_id = FCAN0_ID; instance_id <= FCAN1_ID; instance_id++) { - send_frame[instance_id].candlc = FCAN_SEND_LENGTH; //DLC - if (((int)(uintptr)pvParameters) == 1) + send_frame[instance_id].candlc = FCAN_SEND_LENGTH; + if (ide == EXTEND_FRAME) { - send_frame[instance_id].canid = FCAN_SEND_EXID + count[instance_id]; //EXID //IDE + send_frame[instance_id].canid = FCAN_SEND_EXID + count[instance_id]; send_frame[instance_id].canid |= CAN_EFF_FLAG; - send_max_id = CAN_EFF_MASK | CAN_EFF_FLAG; } else { - send_frame[instance_id].canid = FCAN_SEND_STID + count[instance_id]; //STID + send_frame[instance_id].canid = FCAN_SEND_STID + count[instance_id]; send_frame[instance_id].canid &= CAN_SFF_MASK; - send_max_id = CAN_SFF_MASK; } - for (i = 0; i < send_frame[instance_id].candlc; i++) + for (int i = 0; i < send_frame[instance_id].candlc; i++) { send_frame[instance_id].data[i] = i + (instance_id << 4); } ret = FFreeRTOSCanSend(os_can_ctrl_p[instance_id], &send_frame[instance_id]); if (ret != FCAN_SUCCESS) { - printf("canfd%d send failed.\n", instance_id); + FCAN_TEST_ERROR("canfd%d send failed.", instance_id); + ret = FCAN_INVAL_PARAM; + return ret; } count[instance_id]++; - vTaskDelay(CAN_SEND_PERIOD); - } - if ( (send_frame[instance_id - 1].canid == send_max_id) ) - { - vTaskDelete(NULL); + + /* wait recv interrupt */ + xReturn = xQueueReceive(xQueue_irq, &xReceiveStructure, TIMER_OUT); + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xQueue_irq receive timeout."); + return ret; + } + + /* canfd recv data */ + ret = FFreeRTOSCanfdRecvData(&xReceiveStructure); + if (CANFD_TEST_SUCCESS != ret) + { + FCAN_TEST_ERROR("Canfd recv data failed."); + return ret; + } } } + + return ret; } -static void FFreeRTOSCanfdRecvTask(void *pvParameters) +static FError FFreeRTOSCanfdRecvData(FCanQueueData * xReceiveStructure) { FError ret = FCAN_SUCCESS; - u32 count[FCAN_NUM] = {0}; - int i = 0; - static FCanQueueData xReceiveStructure; FFreeRTOSCan *os_can_p; u32 instance_id = FCAN0_ID; - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) + static u32 recv_count[FCAN_NUM] = {0}; + + os_can_p = xReceiveStructure->os_can_p; + instance_id = os_can_p->can_ctrl.config.instance_id; + ret = FFreeRTOSCanRecv(os_can_p, &recv_frame[instance_id]); + if (FCAN_SUCCESS == ret) { - /* wait recv interrupt give semphore */ - xQueueReceive(xQueue, &xReceiveStructure, portMAX_DELAY); - os_can_p = xReceiveStructure.os_can_p; - instance_id = os_can_p->can_ctrl.config.instance_id; - ret = FFreeRTOSCanRecv(os_can_p, &recv_frame[instance_id]); - if (FCAN_SUCCESS == ret) + FCAN_TEST_DEBUG("canfd%d recv id is 0x%02x.", instance_id, recv_frame[instance_id].canid); + FCAN_TEST_DEBUG("canfd%d recv dlc is %d.", instance_id, recv_frame[instance_id].candlc); + FCAN_TEST_DEBUG("canfd%d recv data is ", instance_id); + for (int i = 0; i < recv_frame[instance_id].candlc; i++) { - printf("\r\ncanfd%d recv id is 0x%02x.\r\n", instance_id, recv_frame[instance_id].canid); - printf("canfd%d recv dlc is %d.\r\n", instance_id, recv_frame[instance_id].candlc); - printf("canfd%d recv data is ", instance_id); - for (i = 0; i < recv_frame[instance_id].candlc; i++) + FCAN_TEST_DEBUG("0x%02x ", recv_frame[instance_id].data[i]); + if (recv_frame[instance_id].data[i] != send_frame[FCAN1_ID - instance_id].data[i]) { - printf("0x%02x ", recv_frame[instance_id].data[i]); - if (recv_frame[instance_id].data[i] != send_frame[FCAN1_ID - instance_id].data[i]) - { - FCAN_TEST_ERROR("\ncount%d = %d: canfd%d recv is not equal to canfd%d send!!!\r\n", instance_id, count[instance_id], instance_id, FCAN1_ID - instance_id); - } + FCAN_TEST_ERROR("count%d = %d: canfd%d recv is not equal to canfd%d send!!!", instance_id, recv_count[instance_id], instance_id, FCAN1_ID - instance_id); } - printf("\ncount%d = %d: canfd%d recv is equal to canfd%d send!!!\r\n", instance_id, count[instance_id], instance_id, FCAN1_ID - instance_id); - count[instance_id]++; } - if ((instance_id == 0) - && ((recv_frame[instance_id].canid == (FCAN_SEND_EXID_MAX | CAN_EFF_FLAG)) - || (recv_frame[instance_id].canid == FCAN_SEND_STID_MAX))) + recv_count[instance_id]++; + FCAN_TEST_DEBUG("count%d = %d: canfd%d recv is equal to canfd%d send!!!", instance_id, recv_count[instance_id], instance_id, FCAN1_ID - instance_id); + } + if (recv_count[instance_id] == FCANFD_SEND_CNT) + { + if (recv_frame[instance_id].canid & CAN_EFF_FLAG) { - FFreeRTOSCanDelete(); + printf("canfd%d -> canfd%d: Extended frame interrupt loop test completed.\r\n", FCAN1_ID - instance_id, instance_id); } + else + { + printf("canfd%d -> canfd%d: Standard frame interrupt loop test completed.\r\n", FCAN1_ID - instance_id, instance_id); + } + recv_count[instance_id] = 0; } + + return ret; } /* create canfd intr test, can0 and can1 loopback */ BaseType_t FFreeRTOSCreateCanfdIntrTestTask(void) { + int task_res = CANFD_UNKNOWN_STATE; BaseType_t xReturn = pdPASS; - BaseType_t timer_started = pdPASS; - test_semaphore = xSemaphoreCreateBinary(); - if (test_semaphore != NULL) + xQueue_task = xQueueCreate(1, sizeof(int)); + if (xQueue_task == NULL) { - xSemaphoreGive(test_semaphore); + FCAN_TEST_ERROR("xQueue_task create failed."); + goto exit; } /* canfd intr example standard frame task */ - xSemaphoreTake(test_semaphore, portMAX_DELAY); - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanInitTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanInitTask",/* 任务名字 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdIntrTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSCanfdIntrStandardTask",/* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ - (void *)0,/* 任务入口函数参数 */ - (UBaseType_t)1, /* 任务的优先级 */ + (void *)STANDARD_FRAME,/* 任务入口函数参数 */ + (UBaseType_t)CANFD_INTR_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xTaskCreate FFreeRTOSCanfdIntrStandardTask failed."); + goto exit; + } + + xReturn = xQueueReceive(xQueue_task, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xQueue_task receive timeout."); + goto exit; + } /* canfd intr example extended frame task */ - xSemaphoreTake(test_semaphore, portMAX_DELAY); - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanInitTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanInitTask2",/* 任务名字 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdIntrTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSCanfdIntrExtendedTask",/* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ - (void *)1,/* 任务入口函数参数 */ - (UBaseType_t)1, /* 任务的优先级 */ + (void *)EXTEND_FRAME,/* 任务入口函数参数 */ + (UBaseType_t)CANFD_INTR_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xTaskCreate FFreeRTOSCanIntrTask failed."); + goto exit; + } - return xReturn; + xReturn = xQueueReceive(xQueue_task, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xQueue_task receive timeout."); + goto exit; + } + +exit: + if (xQueue_task != NULL) + { + vQueueDelete(xQueue_task); + } + + if (task_res != CANFD_TEST_SUCCESS) + { + printf("%s@%d: Canfd intr loopback mode example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return pdFAIL; + } + else + { + printf("%s@%d: Canfd intr loopback mode example [success].\r\n", __func__, __LINE__); + return pdPASS; + } } static void FFreeRTOSCanDelete(void) @@ -455,14 +483,5 @@ static void FFreeRTOSCanDelete(void) FIOMuxDeInit(); /* delete queue */ - vQueueDelete(xQueue); - - xSemaphoreGive(test_semaphore); - - if (recv_handle) - { - vPrintf("\r\nDelete FFreeRTOSCanRecvTask success.\r\n"); - vPrintf("\r\nDelete FFreeRTOSCanSendTask success.\r\n"); - vTaskDelete(recv_handle); - } + vQueueDelete(xQueue_irq); } \ No newline at end of file diff --git a/example/peripheral/can/canfd/src/canfd_polled_loopback_mode_example.c b/example/peripheral/can/canfd/src/canfd_polled_loopback_mode_example.c index 45356964e7b7707f9b596bcbc22268af99b1de9f..cedc28065f369ec3c89c3fc7f1440f29b9f3b7eb 100644 --- a/example/peripheral/can/canfd/src/canfd_polled_loopback_mode_example.c +++ b/example/peripheral/can/canfd/src/canfd_polled_loopback_mode_example.c @@ -14,19 +14,19 @@ * FilePath: canfd_polled_loopback_mode_example.c * Date: 2023-10-11 11:13:48 * LastEditTime: 2023-10-20 11:13:48 - * Description: This file is for CANFD task implementations + * Description: This file is for canfd polled loopback mode example task implementations * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 huangjin 2023/10/7 first commit + * 2.0 huangjin 2024/04/25 add no letter shell mode, adapt to auto-test system */ #include #include #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "timers.h" #include "fcan.h" #include "fcan_os.h" #include "fcpu_info.h" @@ -40,12 +40,24 @@ #define FCAN_TEST_WARN(format, ...) FT_DEBUG_PRINT_W(FCAN_TEST_DEBUG_TAG, format, ##__VA_ARGS__) #define FCAN_TEST_ERROR(format, ...) FT_DEBUG_PRINT_E(FCAN_TEST_DEBUG_TAG, format, ##__VA_ARGS__) +enum +{ + CANFD_TEST_SUCCESS = 0, /*Can intr loopback mode test success*/ + CANFD_INIT_FAILURE = 1, /*Can init step failure */ + CANFD_SEND_FAILURE = 2, /*Can send step failure */ + CANFD_RECV_FAILURE = 3, /*Can recv step failure */ + CANFD_DATA_FAILURE = 4, /*Can data is not equal */ + CANFD_UNKNOWN_STATE = 5, /*Can example unknown state */ +}; + /* canfd frame config */ +#define CANFD_ENABLE TRUE #define FCAN_SEND_STID 0x000007FDU #define FCAN_SEND_EXID 0x1FFFFFFDU #define FCAN_SEND_LENGTH 16 -#define FCAN_SEND_STID_MAX 0x000007FFU -#define FCAN_SEND_EXID_MAX 0x1FFFFFFFU +#define FCAN_SEND_CNT 3 +#define TIMER_OUT ( pdMS_TO_TICKS( 3000UL ) ) +#define CANFD_POLLED_TASK_PRIORITY 3 /* canfd send period */ #define CAN_SEND_PERIOD ( pdMS_TO_TICKS( 100UL )) @@ -55,23 +67,17 @@ #define DATA_BAUD_RATE 2000000 /* Declare a variable of type QueueHandle_t. This is used to store the queue that is accessed by all three tasks. */ -static QueueHandle_t xQueue; - -static xSemaphoreHandle test_semaphore; - -static xTaskHandle send_handle; -static xTaskHandle recv_handle; +static QueueHandle_t xQueue_task; static FFreeRTOSCan *os_can_ctrl_p[FCAN_NUM]; static FCanFrame send_frame[FCAN_NUM]; static FCanFrame recv_frame[FCAN_NUM]; -static void FFreeRTOSCanfdSendTask(void *pvParameters); -static void FFreeRTOSCanfdRecvTask(void *pvParameters); +static FError FFreeRTOSCanfdSendThenRecvData(int ide); +static FError FFreeRTOSCanfdRecvData(u32 instance_id); static void FFreeRTOSCanDelete(void); - static FError FFreeRTOSCanBaudrateSet(FFreeRTOSCan *os_can_p) { FError ret = FCAN_SUCCESS; @@ -104,7 +110,6 @@ static FError FFreeRTOSCanBaudrateSet(FFreeRTOSCan *os_can_p) return ret; } - static FError FFreeRTOSCanIdMaskSet(FFreeRTOSCan *os_can_p, int frame_type) { FError ret = FCAN_SUCCESS; @@ -131,242 +136,264 @@ static FError FFreeRTOSCanIdMaskSet(FFreeRTOSCan *os_can_p, int frame_type) return ret; } -static void FFreeRTOSCanfdInitTask(void *pvParameters) +static FError CanInit(int ide) { - FError ret = FCAN_SUCCESS; - BaseType_t xReturn = pdPASS; u32 instance_id = FCAN0_ID; + FError init_ret = FCAN_FAILURE; u32 tran_mode = FCAN_PROBE_NORMAL_MODE; - boolean use_canfd = TRUE; - - /* The queue is created to hold a maximum of 32 structures of type u32 instance_id . */ - xQueue = xQueueCreate(32, sizeof(u32)); - if (xQueue == NULL) - { - printf("FFreeRTOSCreateCanPolledTestTask FCanQueueData create failed.\r\n"); - } /*init iomux*/ FIOMuxInit(); - for (instance_id = FCAN0_ID; instance_id < FCAN_NUM; instance_id++) + for (instance_id = FCAN0_ID; instance_id <= FCAN1_ID; instance_id++) { FIOPadSetCanMux(instance_id); - /* init canfd controller */ + /* init can controller */ os_can_ctrl_p[instance_id] = FFreeRTOSCanInit(instance_id); if (os_can_ctrl_p[instance_id] == NULL) { - printf("FFreeRTOSCanInit %d failed!!!\r\n", instance_id); - goto canfd_init_exit; + FCAN_TEST_ERROR("FFreeRTOSCanInit %d failed!!!", instance_id); + return init_ret; } /* enable canfd */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_FD_ENABLE, (void *)use_canfd); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_FD_ENABLE, (void *)CANFD_ENABLE); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_FD_ENABLE failed."); - goto canfd_init_exit; + return init_ret; } - /* set canfd baudrate */ - ret = FFreeRTOSCanBaudrateSet(os_can_ctrl_p[instance_id]); - if (FCAN_SUCCESS != ret) + /* set can baudrate */ + init_ret = FFreeRTOSCanBaudrateSet(os_can_ctrl_p[instance_id]); + if (FCAN_SUCCESS != init_ret) { - printf("FFreeRTOSCanInit FFreeRTOSCanBaudrateSet failed!!!\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("FFreeRTOSCanInit FFreeRTOSCanBaudrateSet failed!!!"); + return init_ret; } - /* set canfd id mask */ - ret = FFreeRTOSCanIdMaskSet(os_can_ctrl_p[instance_id], ((int)(uintptr)pvParameters)); - if (FCAN_SUCCESS != ret) + /* set can id mask */ + init_ret = FFreeRTOSCanIdMaskSet(os_can_ctrl_p[instance_id], ide); + if (FCAN_SUCCESS != init_ret) { - printf("FFreeRTOSCanInit FFreeRTOSCanIdMaskSet failed!!!\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("FFreeRTOSCanInit FFreeRTOSCanIdMaskSet failed!!!"); + return init_ret; } /* Identifier mask enable */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ID_MASK_ENABLE, NULL); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ID_MASK_ENABLE, NULL); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ID_MASK_ENABLE failed."); - goto canfd_init_exit; + return init_ret; } - /* set canfd transfer mode */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_MODE_SET, &tran_mode); - if (FCAN_SUCCESS != ret) + /* set can transfer mode */ + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_MODE_SET, &tran_mode); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_MODE_SET failed."); - goto canfd_init_exit; + return init_ret; } /* enable can transfer */ - ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ENABLE, NULL); - if (FCAN_SUCCESS != ret) + init_ret = FFreeRTOSCanControl(os_can_ctrl_p[instance_id], FREERTOS_CAN_CTRL_ENABLE, NULL); + if (FCAN_SUCCESS != init_ret) { FCAN_TEST_ERROR("FFreeRTOSCanControl FREERTOS_CAN_CTRL_ENABLE failed."); - goto canfd_init_exit; + return init_ret; } } - printf("FFreeRTOSCanfdInitTask execute success !!!\r\n"); + return init_ret; +} - if ( ((int)(uintptr)pvParameters) == 0 ) - { - printf("Standard frame test example!!!\r\n"); - } - else if ( ((int)(uintptr)pvParameters) == 1 ) - { - printf("Extended frame test example!!!\r\n"); - } +static void FFreeRTOSCanfdPolledTask(void *pvParameters) +{ + FError ret = FCAN_SUCCESS; + int task_res = 0; + int ide = (int)(uintptr)pvParameters; - /* canfd send task */ - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdSendTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanfdSendTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - pvParameters,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 5, /* 任务的优先级 */ - (TaskHandle_t *)&send_handle); /* 任务控制 */ - if (xReturn != pdPASS) + /* init can controller */ + ret = CanInit(ide); + if (CANFD_TEST_SUCCESS != ret) { - printf("Create FFreeRTOSCanfdSendTask failed.\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("Can init failed."); + task_res = CANFD_INIT_FAILURE; + goto can_test_exit; } - /* canfd recv task */ - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdRecvTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanfdRecvTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 5, /* 任务的优先级 */ - (TaskHandle_t *)&recv_handle); /* 任务控制 */ - if (xReturn != pdPASS) + /* canfd send data */ + ret = FFreeRTOSCanfdSendThenRecvData(ide); + if (CANFD_TEST_SUCCESS != ret) { - printf("Create FFreeRTOSCanfdRecvTask failed.\r\n"); - goto canfd_init_exit; + FCAN_TEST_ERROR("Canfd send then recv data failed."); + task_res = CANFD_DATA_FAILURE; + goto can_test_exit; } -canfd_init_exit: +can_test_exit: + FFreeRTOSCanDelete(); + xQueueSend(xQueue_task, &task_res, 0); vTaskDelete(NULL); } -static void FFreeRTOSCanfdSendTask(void *pvParameters) +static FError FFreeRTOSCanfdSendThenRecvData(int ide) { FError ret = FCAN_SUCCESS; - u32 instance_id = FCAN0_ID; u32 count[FCAN_NUM] = {0}; - u32 send_max_id; - int i = 0; - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) + BaseType_t xReturn = pdPASS; + + for (int j = 0; j < FCAN_SEND_CNT; j++) { - printf("\r\ncanfd send task running.\r\n"); - for (instance_id = FCAN0_ID; instance_id <= FCAN1_ID; instance_id++) + for (u32 instance_id = FCAN0_ID; instance_id <= FCAN1_ID; instance_id++) { - send_frame[instance_id].candlc = FCAN_SEND_LENGTH; //DLC - if (((int)(uintptr)pvParameters) == 1) + send_frame[instance_id].candlc = FCAN_SEND_LENGTH; + if (ide == EXTEND_FRAME) { - send_frame[instance_id].canid = FCAN_SEND_EXID + count[instance_id]; //EXID //IDE + send_frame[instance_id].canid = FCAN_SEND_EXID + count[instance_id]; send_frame[instance_id].canid |= CAN_EFF_FLAG; - send_max_id = CAN_EFF_MASK | CAN_EFF_FLAG; } else { - send_frame[instance_id].canid = FCAN_SEND_STID + count[instance_id]; //STID + send_frame[instance_id].canid = FCAN_SEND_STID + count[instance_id]; send_frame[instance_id].canid &= CAN_SFF_MASK; - send_max_id = CAN_SFF_MASK; } - for (i = 0; i < send_frame[instance_id].candlc; i++) + for (int i = 0; i < send_frame[instance_id].candlc; i++) { send_frame[instance_id].data[i] = i + (instance_id << 4); } ret = FFreeRTOSCanSend(os_can_ctrl_p[instance_id], &send_frame[instance_id]); if (ret != FCAN_SUCCESS) { - printf("canfd%d send failed.\n", instance_id); + FCAN_TEST_ERROR("canfd%d send failed.\n", instance_id); } count[instance_id]++; vTaskDelay(CAN_SEND_PERIOD); - xQueueSendToBack(xQueue, &instance_id, portMAX_DELAY); - } - if ( (send_frame[instance_id - 1].canid == send_max_id) ) - { - vTaskDelete(NULL); + + /* can recv data */ + ret = FFreeRTOSCanfdRecvData(instance_id); + if (CANFD_TEST_SUCCESS != ret) + { + FCAN_TEST_ERROR("Can recv data failed."); + return ret; + } } } + + return ret; } -static void FFreeRTOSCanfdRecvTask(void *pvParameters) +static FError FFreeRTOSCanfdRecvData(u32 instance_id) { FError ret = FCAN_SUCCESS; - u32 count[FCAN_NUM] = {0}; - int i = 0; - u32 instance_id = FCAN1_ID; - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) + static u32 recv_count[FCAN_NUM] = {0}; + + instance_id = FCAN1_ID - instance_id; + ret = FFreeRTOSCanRecv(os_can_ctrl_p[instance_id], &recv_frame[instance_id]); + if (FCAN_SUCCESS == ret) { - /* wait canfd send give semphore */ - xQueueReceive(xQueue, &instance_id, portMAX_DELAY); - instance_id = FCAN1_ID - instance_id; - ret = FFreeRTOSCanRecv(os_can_ctrl_p[instance_id], &recv_frame[instance_id]); - if (FCAN_SUCCESS == ret) + FCAN_TEST_DEBUG("canfd%d recv id is 0x%02x.", instance_id, recv_frame[instance_id].canid); + FCAN_TEST_DEBUG("canfd%d recv dlc is %d.", instance_id, recv_frame[instance_id].candlc); + FCAN_TEST_DEBUG("canfd%d recv data is ", instance_id); + for (int i = 0; i < recv_frame[instance_id].candlc; i++) { - printf("\r\ncanfd%d recv id is 0x%02x.\r\n", instance_id, recv_frame[instance_id].canid); - printf("canfd%d recv dlc is %d.\r\n", instance_id, recv_frame[instance_id].candlc); - printf("canfd%d recv data is ", instance_id); - for (i = 0; i < recv_frame[instance_id].candlc; i++) + FCAN_TEST_DEBUG("0x%02x ", recv_frame[instance_id].data[i]); + if (recv_frame[instance_id].data[i] != send_frame[FCAN1_ID - instance_id].data[i]) { - printf("0x%02x ", recv_frame[instance_id].data[i]); - if (recv_frame[instance_id].data[i] != send_frame[FCAN1_ID - instance_id].data[i]) - { - FCAN_TEST_ERROR("\ncount%d = %d: canfd%d recv is not equal to canfd%d send!!!\r\n", instance_id, count[instance_id], instance_id, FCAN1_ID - instance_id); - } + FCAN_TEST_ERROR("count%d = %d: canfd%d recv is not equal to canfd%d send!!!", instance_id, recv_count[instance_id], instance_id, FCAN1_ID - instance_id); } - printf("\ncount%d = %d: canfd%d recv is equal to canfd%d send!!!\r\n", instance_id, count[instance_id], instance_id, FCAN1_ID - instance_id); - count[instance_id]++; } - if ((instance_id == 0) - && ((recv_frame[instance_id].canid == (FCAN_SEND_EXID_MAX | CAN_EFF_FLAG)) - || (recv_frame[instance_id].canid == FCAN_SEND_STID_MAX))) + recv_count[instance_id]++; + FCAN_TEST_DEBUG("count%d = %d: canfd%d recv is equal to canfd%d send!!!", instance_id, recv_count[instance_id], instance_id, FCAN1_ID - instance_id); + } + if (recv_count[instance_id] == FCAN_SEND_CNT) + { + if (recv_frame[instance_id].canid & CAN_EFF_FLAG) + { + printf("canfd%d -> canfd%d: Extended frame polled loop test completed.\r\n", FCAN1_ID - instance_id, instance_id); + } + else { - FFreeRTOSCanDelete(); + printf("canfd%d -> canfd%d: Standard frame polled loop test completed.\r\n", FCAN1_ID - instance_id, instance_id); } - } + recv_count[instance_id] = 0; + } + + return ret; } /* create canfd polled test, can0 and can1 loopback */ BaseType_t FFreeRTOSCreateCanfdPolledTestTask(void) { + int task_res = CANFD_UNKNOWN_STATE; BaseType_t xReturn = pdPASS; - BaseType_t timer_started = pdPASS; - test_semaphore = xSemaphoreCreateBinary(); - if (test_semaphore != NULL) + xQueue_task = xQueueCreate(1, sizeof(int)); + if (xQueue_task == NULL) { - xSemaphoreGive(test_semaphore); + FCAN_TEST_ERROR("xQueue_task create failed."); + goto exit; } /* canfd polled example standard frame task */ - xSemaphoreTake(test_semaphore, portMAX_DELAY); - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdInitTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanfdInitTask",/* 任务名字 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdPolledTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSCanfdPolledStandardTask",/* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ - (void *)0,/* 任务入口函数参数 */ - (UBaseType_t)1, /* 任务的优先级 */ + (void *)STANDARD_FRAME,/* 任务入口函数参数 */ + (UBaseType_t)CANFD_POLLED_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xTaskCreate FFreeRTOSCanfdPolledStandardTask failed."); + goto exit; + } + + xReturn = xQueueReceive(xQueue_task, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xQueue_task receive timeout."); + goto exit; + } /* canfd polled example extended frame task */ - xSemaphoreTake(test_semaphore, portMAX_DELAY); - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdInitTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSCanfdInitTask2",/* 任务名字 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSCanfdPolledTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSCanfdPolledExtendedTask",/* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ - (void *)1,/* 任务入口函数参数 */ - (UBaseType_t)1, /* 任务的优先级 */ + (void *)EXTEND_FRAME,/* 任务入口函数参数 */ + (UBaseType_t)CANFD_POLLED_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xTaskCreate FFreeRTOSCanfdPolledExtendedTask failed."); + goto exit; + } + + xReturn = xQueueReceive(xQueue_task, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FCAN_TEST_ERROR("xQueue_task receive timeout."); + goto exit; + } - return xReturn; +exit: + if (xQueue_task != NULL) + { + vQueueDelete(xQueue_task); + } + + if (task_res != CANFD_TEST_SUCCESS) + { + printf("%s@%d: Canfd polled loopback mode example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return pdFAIL; + } + else + { + printf("%s@%d: Canfd polled loopback mode example [success].\r\n", __func__, __LINE__); + return pdPASS; + } } static void FFreeRTOSCanDelete(void) @@ -377,16 +404,4 @@ static void FFreeRTOSCanDelete(void) /*iopad deinit */ FIOMuxDeInit(); - - /* delete queue */ - vQueueDelete(xQueue); - - xSemaphoreGive(test_semaphore); - - if (recv_handle) - { - vPrintf("\r\nDelete FFreeRTOSCanRecvTask success.\r\n"); - vPrintf("\r\nDelete FFreeRTOSCanSendTask success.\r\n"); - vTaskDelete(recv_handle); - } } \ No newline at end of file diff --git a/example/peripheral/can/canfd/src/cmd_canfd.c b/example/peripheral/can/canfd/src/cmd_canfd.c index f3b89860f57f6ddbbc6974b3cf99de6f05e7fff9..ecbeaa2e45720b4dbfd0bb828fed564c5e2e868a 100644 --- a/example/peripheral/can/canfd/src/cmd_canfd.c +++ b/example/peripheral/can/canfd/src/cmd_canfd.c @@ -20,26 +20,32 @@ * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 huangjin 2023/10/20 first commit + * 2.0 huangjin 2024/04/25 add no letter shell mode, adapt to auto-test system */ -#include "shell.h" -#include "canfd_intr_loopback_mode_example.h" -#include "canfd_polled_loopback_mode_example copy.h" -#include "canfd_id_filter_example.h" +#include "sdkconfig.h" +#include "FreeRTOS.h" +#include "canfd_example.h" #include +#include "task.h" #include +#include "strto.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "../src/shell.h" static void CreateTasksCmdUsage(void) { printf("Usage:\r\n"); - printf(" canfd intr \r\n"); - printf(" -- Create canfd interrupt test example now. \r\n"); - printf(" canfd polled \r\n"); - printf(" -- Create canfd polled test example now. \r\n"); - printf(" canfd filter \r\n"); - printf(" -- Create canfd filter test example now. \r\n"); + printf("canfd intr \r\n"); + printf("-- Create canfd interrupt test example now. \r\n"); + printf("canfd polled \r\n"); + printf("-- Create canfd polled test example now. \r\n"); +#if defined(CONFIG_E2000D_DEMO_BOARD) || defined(CONFIG_E2000Q_DEMO_BOARD) + printf("canfd filter \r\n"); + printf("-- Create canfd filter test example now. \r\n"); +#endif } -int CreateTasksCmd(int argc, char *argv[]) +int CanfdCmdEntry(int argc, char *argv[]) { if (argc < 2) { @@ -54,10 +60,12 @@ int CreateTasksCmd(int argc, char *argv[]) { FFreeRTOSCreateCanfdPolledTestTask(); } +#if defined(CONFIG_E2000D_DEMO_BOARD) || defined(CONFIG_E2000Q_DEMO_BOARD) else if (!strcmp(argv[1], "filter")) { FFreeRTOSCanfdCreateFilterTestTask(); } +#endif else { printf("Error: Invalid arguments. \r\n"); @@ -67,6 +75,5 @@ int CreateTasksCmd(int argc, char *argv[]) return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), canfd, CreateTasksCmd, canfd creating test); - - +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), canfd, CanfdCmdEntry, test freertos canfd driver); +#endif \ No newline at end of file diff --git a/example/peripheral/dma/ddma/src/cmd_ddma.c b/example/peripheral/dma/ddma/src/cmd_ddma.c index 3891b6839ff1b7fd636a0a85c7cdee06032a6fe9..f5d7a2975fd1ef38fc036337f4efea0fd883f157 100644 --- a/example/peripheral/dma/ddma/src/cmd_ddma.c +++ b/example/peripheral/dma/ddma/src/cmd_ddma.c @@ -79,6 +79,9 @@ void DdmaTasksEntry(void) u32 bytes = 32; u32 spi_id = USED_SPI_ID; FFreeRTOSRunDDMASpiLoopback(spi_id, bytes); + + /* end flag */ + printf("[test_end]\r\n"); vTaskDelete(NULL); } #endif \ No newline at end of file diff --git a/example/peripheral/dma/gdma/src/gdma_memcpy.c b/example/peripheral/dma/gdma/src/gdma_memcpy.c index 57ef703305e9edbf7682d17d1fa573e9604e3eb4..e98ba058854f29c96ccd84c82ea76d857c608b5e 100644 --- a/example/peripheral/dma/gdma/src/gdma_memcpy.c +++ b/example/peripheral/dma/gdma/src/gdma_memcpy.c @@ -232,7 +232,7 @@ int FFreeRTOSGdmaMemcpy(void) goto exit; } - exit: +exit: if (xQueue != NULL) { vQueueDelete(xQueue); diff --git a/example/peripheral/gpio/README.md b/example/peripheral/gpio/README.md index ce30222355c67cf7e1690d935ff3b3817656cb37..fda1a66ee226cee13a4bedd6d0de3665151754d0 100644 --- a/example/peripheral/gpio/README.md +++ b/example/peripheral/gpio/README.md @@ -18,10 +18,8 @@ GPIO (General-purpose input/output),即通用型输入输出,其引脚可以 - 杜邦线 #### 2.1.1 对于E2000 D/Q Demo 板 -- 在本例程中短接 GPIO-3-A-4 和 GPIO-3-4-5,GPIO-3-4-5作为GPIO输出引脚,GPIO-3-A-4作为GPIO输入引脚,在J30位置如下图所示: - -![](./figs/pin_connect_gpio3.jpg) - +- 在本例程中短接 GPIO-4-A-11 和 GPIO-4-A-12,GPIO-4-A-11作为GPIO输入引脚,GPIO-4-A-12作为GPIO输出引脚,在J30位置如下图所示: +![](./figs/pin_gpio_intr_board.png) #### 2.1.2 对于飞腾派 - 需要用杜邦线短接GPIO3_1与GPIO3_2,分别对应飞腾派上的J1组引脚的第11号与第16号引脚 diff --git a/example/peripheral/gpio/figs/pin_connect_gpio3.jpg b/example/peripheral/gpio/figs/pin_connect_gpio3.jpg deleted file mode 100644 index 808055f73d911cf0aae9204b3b2ba360cde79093..0000000000000000000000000000000000000000 Binary files a/example/peripheral/gpio/figs/pin_connect_gpio3.jpg and /dev/null differ diff --git a/example/peripheral/gpio/figs/pin_connect_gpio4.jpg b/example/peripheral/gpio/figs/pin_connect_gpio4.jpg deleted file mode 100644 index f509f182d3c2d692d0017282e0b41c40bb1a4939..0000000000000000000000000000000000000000 Binary files a/example/peripheral/gpio/figs/pin_connect_gpio4.jpg and /dev/null differ diff --git a/example/peripheral/gpio/figs/pin_gpio_intr_board.png b/example/peripheral/gpio/figs/pin_gpio_intr_board.png new file mode 100644 index 0000000000000000000000000000000000000000..a8d138a3c8c9a11165800b4c90cedc3c30425864 Binary files /dev/null and b/example/peripheral/gpio/figs/pin_gpio_intr_board.png differ diff --git a/example/peripheral/gpio/sdkconfig b/example/peripheral/gpio/sdkconfig index 42d5d1e86b7308aea0246ed1ac552f1442805b41..cddd0fe6a8acfbd2ae071208a388bb02827ad307 100644 --- a/example/peripheral/gpio/sdkconfig +++ b/example/peripheral/gpio/sdkconfig @@ -39,16 +39,15 @@ CONFIG_USE_MMU=y # # Soc configuration # -# CONFIG_TARGET_PHYTIUMPI is not set +CONFIG_TARGET_PHYTIUMPI=y # CONFIG_TARGET_E2000Q is not set -CONFIG_TARGET_E2000D=y +# CONFIG_TARGET_E2000D is not set # CONFIG_TARGET_E2000S is not set # CONFIG_TARGET_FT2004 is not set # CONFIG_TARGET_D2000 is not set # CONFIG_TARGET_PD2308 is not set -CONFIG_SOC_NAME="e2000" -CONFIG_TARGET_TYPE_NAME="d" -CONFIG_SOC_CORE_NUM=2 +CONFIG_SOC_NAME="phytiumpi" +CONFIG_SOC_CORE_NUM=4 CONFIG_F32BIT_MEMORY_ADDRESS=0x80000000 CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 @@ -63,22 +62,21 @@ CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # # Board Configuration # -CONFIG_E2000D_DEMO_BOARD=y -CONFIG_BOARD_NAME="demo" - -# -# IO mux configuration when board start up -# +CONFIG_BOARD_NAME="firefly" # CONFIG_USE_SPI_IOPAD is not set # CONFIG_USE_GPIO_IOPAD is not set # CONFIG_USE_CAN_IOPAD is not set # CONFIG_USE_QSPI_IOPAD is not set # CONFIG_USE_PWM_IOPAD is not set -# CONFIG_USE_ADC_IOPAD is not set # CONFIG_USE_MIO_IOPAD is not set # CONFIG_USE_TACHO_IOPAD is not set # CONFIG_USE_UART_IOPAD is not set # CONFIG_USE_THIRD_PARTY_IOPAD is not set +CONFIG_FIREFLY_DEMO_BOARD=y + +# +# IO mux configuration when board start up +# # end of IO mux configuration when board start up # CONFIG_CUS_DEMO_BOARD is not set diff --git a/example/peripheral/gpio/sdkconfig.h b/example/peripheral/gpio/sdkconfig.h index 91c03b5a5ade3145bcafa7b45cc5076cbd6cd2dd..b35ea0bbcd02ab2f51917097b1ed9ce3ff842434 100644 --- a/example/peripheral/gpio/sdkconfig.h +++ b/example/peripheral/gpio/sdkconfig.h @@ -37,16 +37,15 @@ /* Soc configuration */ -/* CONFIG_TARGET_PHYTIUMPI is not set */ +#define CONFIG_TARGET_PHYTIUMPI /* CONFIG_TARGET_E2000Q is not set */ -#define CONFIG_TARGET_E2000D +/* CONFIG_TARGET_E2000D is not set */ /* CONFIG_TARGET_E2000S is not set */ /* CONFIG_TARGET_FT2004 is not set */ /* CONFIG_TARGET_D2000 is not set */ /* CONFIG_TARGET_PD2308 is not set */ -#define CONFIG_SOC_NAME "e2000" -#define CONFIG_TARGET_TYPE_NAME "d" -#define CONFIG_SOC_CORE_NUM 2 +#define CONFIG_SOC_NAME "phytiumpi" +#define CONFIG_SOC_CORE_NUM 4 #define CONFIG_F32BIT_MEMORY_ADDRESS 0x80000000 #define CONFIG_F32BIT_MEMORY_LENGTH 0x80000000 #define CONFIG_F64BIT_MEMORY_ADDRESS 0x2000000000 @@ -60,21 +59,20 @@ /* Board Configuration */ -#define CONFIG_E2000D_DEMO_BOARD -#define CONFIG_BOARD_NAME "demo" - -/* IO mux configuration when board start up */ - +#define CONFIG_BOARD_NAME "firefly" /* CONFIG_USE_SPI_IOPAD is not set */ /* CONFIG_USE_GPIO_IOPAD is not set */ /* CONFIG_USE_CAN_IOPAD is not set */ /* CONFIG_USE_QSPI_IOPAD is not set */ /* CONFIG_USE_PWM_IOPAD is not set */ -/* CONFIG_USE_ADC_IOPAD is not set */ /* CONFIG_USE_MIO_IOPAD is not set */ /* CONFIG_USE_TACHO_IOPAD is not set */ /* CONFIG_USE_UART_IOPAD is not set */ /* CONFIG_USE_THIRD_PARTY_IOPAD is not set */ +#define CONFIG_FIREFLY_DEMO_BOARD + +/* IO mux configuration when board start up */ + /* end of IO mux configuration when board start up */ /* CONFIG_CUS_DEMO_BOARD is not set */ diff --git a/example/peripheral/gpio/src/cmd_gpio.c b/example/peripheral/gpio/src/cmd_gpio.c index 5a393b8b9303eab13c1dd0bc7fa26dbcb6c4164a..9e226e3c2ef5844cc5f3f78f91c430e5711417c6 100644 --- a/example/peripheral/gpio/src/cmd_gpio.c +++ b/example/peripheral/gpio/src/cmd_gpio.c @@ -47,7 +47,7 @@ static void GpioCmdUsage(void) { printf("Usage:\r\n"); - printf("pin io-irq\r\n"); + printf("gpio io-irq\r\n"); printf("-- Demo to test gpio interrupt\r\n"); } static int GpioCmdEntry(int argc, char *argv[]) diff --git a/example/peripheral/gpio/src/gpio_io_irq.c b/example/peripheral/gpio/src/gpio_io_irq.c index d51654f449f5b8903de46a081b55358e95b1667b..ddc9175a7d96738200d0292c10d3ac2aecd34aaa 100644 --- a/example/peripheral/gpio/src/gpio_io_irq.c +++ b/example/peripheral/gpio/src/gpio_io_irq.c @@ -36,8 +36,8 @@ #include "gpio_io_irq.h" /************************** Constant Definitions *****************************/ #if defined(CONFIG_E2000D_DEMO_BOARD) || defined(CONFIG_E2000Q_DEMO_BOARD) - #define IN_PIN_INDEX FFREERTOS_GPIO_PIN_INDEX(3, 0, 5) /* GPIO 3-A-5 */ - #define OUT_PIN_INDEX FFREERTOS_GPIO_PIN_INDEX(3, 0, 4) + #define IN_PIN_INDEX FFREERTOS_GPIO_PIN_INDEX(4, 0, 11) /* GPIO 4-A-11 */ + #define OUT_PIN_INDEX FFREERTOS_GPIO_PIN_INDEX(4, 0, 12) #endif #ifdef CONFIG_FIREFLY_DEMO_BOARD diff --git a/example/peripheral/i2c/README.md b/example/peripheral/i2c/README.md index 36eeec30ecc3b3db2d2baef7cca601d1c179dcb0..eece4961044e99d48c215efbfc59dabc07a650b6 100644 --- a/example/peripheral/i2c/README.md +++ b/example/peripheral/i2c/README.md @@ -2,38 +2,66 @@ ## 1. 例程介绍 -本例程示范了freertos环境下的i2c的读写使用,包括i2c的初始化、写、读和去初始化操作; -(支持E2000DQ demo开发板)实现了读取RTC的例程。 -(支持firefly开发板)本例程实现了I2C主从(Master-Slave)通信,主机侧是开发板的MIO1,负责发起I2C数据读写,此例程中我们master端仅采用poll模式去读写操作,从机侧是开发板的MIO2模拟eeprom,负责响应I2C数据读写,采用中断响应方式,从机侧实现了一个虚拟的EEPROM缓冲区,模拟主机侧写入和读取数据的过程。 +I2C主从机模拟Eeprom通信测试例程(i2c_ms_example.c) +注:该例程目前仅支持在PhytiumPi开发板上进行测试,E2000Q/D Demo板未引出两组I2C或MIO控制器引脚 +- 初始化MIO1控制器,设置为主机工作模式;初始化MIO2控制器,设置为从机工作模式,从机地址设置为0x30 +- 主机分别向从机内部偏移地址0x01和0x31处写入16字节长度数组(0x01-0x10) +- 主机依次读取从机内部偏移地址0x01和0x31两处地址16字节长度的数据,与上述写入数据进行对比并打印 +- 打印从机内部所有存储数据,观测已写入内容 +- 去初始化MIO1/MIO2控制器 + +I2C与RTC通信测试例程(i2c_rtc_example.c) +注:该例程目前仅支持在E2000Q/D Demo开发板上进行测试,PhytiumPi开发板未内嵌RTC芯片 +- 初始化MIO9控制器,设置为主机工作模式 +- 向RTC芯片写入初始化时间进行,并开启计时 +- 每间隔1s,连续两次读取RTC内部时间并打印,观测打印结果 +- 去初始化MIO9控制器 ## 2. 如何使用例程 本例程需要用到 - Phytium开发板(E2000DQ/phytiumpi) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 本例程支持的硬件平台包括 -- E2000DQ demo、phytiumpi开发板 +- E2000D/Q demo、phytiumpi开发板 对应的配置项是 -- CONFIG_TARGET_E2000D、 CONFIG_TARGET_E2000Q +- CONFIG_TARGET_E2000D +- CONFIG_TARGET_E2000Q - CONFIG_TARGET_PHYTIUMPI ### 2.1.1 硬件连线 -- E2000 +- 下图所示为E2000D/Q demo开发板RTC芯片 -![hardware_e2000](./figs/E2000_1339.png) +![e2000_1339](figs/e2000_1339.jpg) -- phytiumpi -![phytiumpi](./figs/hw_i2c_pi.png) +- PhytiumPi请按照下图,将PIN_3与PIN_8引脚相连,PIN_5与PIN_10引脚相连 + +![phytiumpi](figs/hw_i2c_pi.png) + +如需使用其他控制器测试,可参考下表进行连接,修改`i2c_ms_example.c`,`I2C_MS_TEST_MASTER`和`I2C_MS_TEST_SLAVE`即可 + +| **引脚** | **控制器与通道** | +| :----------: | :-----------------| +| J1 PIN_3 | MIO1 I2C_SDA | +| J1 PIN_5 | MIO1 I2C_SCL | +| J1 PIN_8 | MIO2 I2C_SDA | +| J1 PIN_10 | MIO2 I2C_SCL | +| J1 PIN_27 | MIO8 I2C_SDA | +| J1 PIN_28 | MIO8 I2C_SCL | +| J1 PIN_16 | MIO10 I2C_SDA | +| J1 PIN_11 | MIO10 I2C_SCL | +| J2 PIN_4 | MIO0 I2C_SDA | +| J2 PIN_2 | MIO0 I2C_SCL | ### 2.2 SDK配置方法 @@ -132,15 +160,15 @@ bootelf -p 0x90100000 i2c rtc ``` -![e2000d](figs/E2000_rtc.png) +![rtc_example](figs/rtc_example.png) - phytiumpi 支持主从机进行通信,从设备控制器模拟eeprom ``` -i2c rw +i2c ms_example ``` -![phytiumpi](./figs/phytiumpi.png) +![ms_example](./figs/ms_example.png) ## 3. 如何解决问题 diff --git a/example/peripheral/i2c/figs/E2000_1339.png b/example/peripheral/i2c/figs/E2000_1339.png deleted file mode 100644 index 9574b8a4d13dc3cb61450c81164f874aadbc3870..0000000000000000000000000000000000000000 Binary files a/example/peripheral/i2c/figs/E2000_1339.png and /dev/null differ diff --git a/example/peripheral/i2c/figs/E2000_rtc.png b/example/peripheral/i2c/figs/E2000_rtc.png deleted file mode 100644 index dedd52ab3a320eecd0a36edfb79dfaf318ddedc4..0000000000000000000000000000000000000000 Binary files a/example/peripheral/i2c/figs/E2000_rtc.png and /dev/null differ diff --git a/example/peripheral/i2c/figs/e2000_1339.jpg b/example/peripheral/i2c/figs/e2000_1339.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b6a014ecfffc46b3cce90b2dccfca628b555ed2c Binary files /dev/null and b/example/peripheral/i2c/figs/e2000_1339.jpg differ diff --git a/example/peripheral/i2c/figs/hw_i2c_pi.png b/example/peripheral/i2c/figs/hw_i2c_pi.png index 4fa1f052fe2b9e59d2c98ac7d3f58864a6985caa..c1df6126259f94f8ddf40009116e0cf616d67999 100644 Binary files a/example/peripheral/i2c/figs/hw_i2c_pi.png and b/example/peripheral/i2c/figs/hw_i2c_pi.png differ diff --git a/example/peripheral/i2c/figs/ms_example.png b/example/peripheral/i2c/figs/ms_example.png new file mode 100644 index 0000000000000000000000000000000000000000..36753cda245c878336b80156b2c47bf0a857dfc1 Binary files /dev/null and b/example/peripheral/i2c/figs/ms_example.png differ diff --git a/example/peripheral/i2c/figs/phytiumpi.png b/example/peripheral/i2c/figs/phytiumpi.png deleted file mode 100644 index 78dc38aab05da5c1f9fdc339999d5ef8ca7d6dc7..0000000000000000000000000000000000000000 Binary files a/example/peripheral/i2c/figs/phytiumpi.png and /dev/null differ diff --git a/example/peripheral/i2c/figs/rtc_example.png b/example/peripheral/i2c/figs/rtc_example.png new file mode 100644 index 0000000000000000000000000000000000000000..2b01610d18b7f9b5654b0faec76ce6cc0ef44d44 Binary files /dev/null and b/example/peripheral/i2c/figs/rtc_example.png differ diff --git a/example/peripheral/i2c/inc/i2c_example.h b/example/peripheral/i2c/inc/i2c_example.h index 87ac39b1e4c459b559566296cfec1ea0f9bd4f67..ff0ea27d199ef73523a3127e497816020d8251cf 100644 --- a/example/peripheral/i2c/inc/i2c_example.h +++ b/example/peripheral/i2c/inc/i2c_example.h @@ -20,17 +20,17 @@ * Ver    Who         Date          Changes * -----  ------      --------     -------------------------------------- * 1.0 liushengming 2022/11/25 init commit + * 1.1 zhangyan 2024/4/18 add no letter shell mode, adapt to auto-test system */ #ifndef I2C_EXAMPLE_H #define I2C_EXAMPLE_H -#include "fi2c_os.h" +#include "FreeRTOS.h" #ifdef __cplusplus extern "C" { #endif - /***************************** Include Files *********************************/ /************************** Definitions *****************************/ @@ -43,8 +43,6 @@ extern "C" /* i2c write and read test */ BaseType_t FFreeRTOSI2cRtcCreate(void); BaseType_t FFreeRTOSI2cLoopbackCreate(void); -/* dump buffer of slave */ -void FFreeRTOSI2cSlaveDump(FFreeRTOSI2c *os_i2c_p); #ifdef __cplusplus } diff --git a/example/peripheral/i2c/main.c b/example/peripheral/i2c/main.c index 1a9b4ef008adf100e3e5b1735575f8b60e27de92..a3ae60b2b811c8becb759581e6bf9fd2f9ccc491 100644 --- a/example/peripheral/i2c/main.c +++ b/example/peripheral/i2c/main.c @@ -20,22 +20,52 @@ * Ver    Who         Date          Changes * -----  ------      --------     -------------------------------------- * 1.0 liushengming 2022/11/25 init commit + * 1.1 zhangyan 2024/4/18 add no letter shell mode, adapt to auto-test system */ #include +#include "sdkconfig.h" +#include "FreeRTOS.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" +#else +#include "task.h" #include "i2c_example.h" +#define I2C_EXAMPLE_TASK_PRIORITY 2 +void I2cExampleTaskEntry() +{ +#if defined(CONFIG_E2000D_DEMO_BOARD)||defined(CONFIG_E2000Q_DEMO_BOARD) + FFreeRTOSI2cRtcCreate(); +#elif defined(CONFIG_FIREFLY_DEMO_BOARD) + FFreeRTOSI2cLoopbackCreate(); +#endif + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif int main(void) { BaseType_t ret; +#ifdef CONFIG_USE_LETTER_SHELL ret = LSUserShellTask(); if (ret != pdPASS) { goto FAIL_EXIT; } +#else + taskENTER_CRITICAL(); /*进入临界区*/ + ret = xTaskCreate((TaskFunction_t)I2cExampleTaskEntry, /* 任务入口函数 */ + (const char *)"I2cExampleTaskEntry", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)I2C_EXAMPLE_TASK_PRIORITY, /* 任务的优先级 */ + NULL); + taskEXIT_CRITICAL(); /*退出临界区*/ +#endif vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ diff --git a/example/peripheral/i2c/makefile b/example/peripheral/i2c/makefile index 8cdbb131737371bf472dd0695f73ceba32b2c1a4..f51593a5e66ce8642c197506ee04f4ee4baab8a6 100644 --- a/example/peripheral/i2c/makefile +++ b/example/peripheral/i2c/makefile @@ -2,12 +2,24 @@ PROJECT_DIR = $(CURDIR) FREERTOS_SDK_DIR = $(CURDIR)/../../.. - +include $(PROJECT_DIR)/sdkconfig # # 设置启动镜像名 BOOT_IMG_NAME ?= freertos USER_CSRC := main.c -USER_CSRC += $(wildcard src/*.c) +USER_CSRC += src/cmd_i2c.c + +ifdef CONFIG_FIREFLY_DEMO_BOARD +USER_CSRC += src/i2c_ms_example.c +endif + +ifdef CONFIG_E2000Q_DEMO_BOARD +USER_CSRC += src/i2c_rtc_example.c +endif + +ifdef CONFIG_E2000D_DEMO_BOARD +USER_CSRC += src/i2c_rtc_example.c +endif USER_ASRC := USER_CXXSRC := diff --git a/example/peripheral/i2c/src/cmd_i2c.c b/example/peripheral/i2c/src/cmd_i2c.c index 39e5126f00e6edfeba3b5717bc404e4864f2ca81..3c83cfa57a9bab1d6a3abbd2a417ed1f3facc559 100644 --- a/example/peripheral/i2c/src/cmd_i2c.c +++ b/example/peripheral/i2c/src/cmd_i2c.c @@ -27,13 +27,13 @@ #include "strto.h" #include "sdkconfig.h" #include "FreeRTOS.h" -#include "shell.h" -#include "fi2c_os.h" #include "i2c_example.h" /************************** Function Prototypes ******************************/ /*****************************************************************************/ +#ifdef CONFIG_USE_LETTER_SHELL +#include "shell.h" static void FI2cExampleUsage() { printf("Usage:\r\n"); @@ -42,7 +42,7 @@ static void FI2cExampleUsage() printf(" -- E2000 demo board set time and read it.\r\n"); #endif #if defined(CONFIG_FIREFLY_DEMO_BOARD) - printf(" i2c rw\r\n"); + printf(" i2c ms_example\r\n"); printf(" -- firefly board,Two i2c controllers are used for master-slave communication.\r\n"); #endif } @@ -67,7 +67,7 @@ static int I2cCmdEntry(int argc, char *argv[]) } #endif #if defined(CONFIG_FIREFLY_DEMO_BOARD) - else if (!strcmp(argv[1], "rw")) + else if (!strcmp(argv[1], "ms_example")) { ret = FFreeRTOSI2cLoopbackCreate(); if (ret != pdPASS) @@ -81,3 +81,4 @@ static int I2cCmdEntry(int argc, char *argv[]) } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), i2c, I2cCmdEntry, test freertos i2c driver); +#endif diff --git a/example/peripheral/i2c/src/i2c_ms_example.c b/example/peripheral/i2c/src/i2c_ms_example.c index 9cb2318e84dd0fbe034c35e6c0f777bd3877460a..1a1627d9d7a52013d63ec1d23aa90be0dd454b14 100644 --- a/example/peripheral/i2c/src/i2c_ms_example.c +++ b/example/peripheral/i2c/src/i2c_ms_example.c @@ -20,68 +20,67 @@ * Ver    Who         Date          Changes * -----  ------      --------     -------------------------------------- * 1.0 liushengming 2023/09/25 init commit + * 1.1 zhangyan 2024/4/18 add no letter shell mode, adapt to auto-test system */ #include #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "fi2c.h" -#include "fi2c_hw.h" #include "fi2c_os.h" -#include "timers.h" -#include "fcpu_info.h" #include "i2c_example.h" -#include "fparameters.h" #include "fio_mux.h" #include "sdkconfig.h" #include "fdebug.h" #include "ftypes.h" #include "finterrupt.h" +#define FI2C_DEBUG_TAG "I2C_MS_TEST" +#define FI2C_ERROR(format, ...) FT_DEBUG_PRINT_E(FI2C_DEBUG_TAG, format, ##__VA_ARGS__) +#define FI2C_WARN(format, ...) FT_DEBUG_PRINT_W(FI2C_DEBUG_TAG, format, ##__VA_ARGS__) +#define FI2C_INFO(format, ...) FT_DEBUG_PRINT_I(FI2C_DEBUG_TAG, format, ##__VA_ARGS__) +#define FI2C_DEBUG(format, ...) FT_DEBUG_PRINT_D(FI2C_DEBUG_TAG, format, ##__VA_ARGS__) + +#if defined(CONFIG_FIREFLY_DEMO_BOARD) +#define I2C_MS_TEST_MASTER_DEVICE FMIO1_ID +#define I2C_MS_TEST_SLAVE_DEVICE FMIO2_ID +#endif + /* write and read task delay in milliseconds */ #define TASK_DELAY_MS 1000UL - +#define I2C_MS_TEST_TASK_PRIORITY 3 +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) /* slave address */ /* Notice! Using addresses above 0x50 may cause the loopback test to fail */ -#define MASTER_SLAVE_ADDR 0x01 +#define MASTER_SLAVE_ADDR 0x30 -#define DAT_LENGTH 15 +#define DAT_LENGTH 16 static char data_w[DAT_LENGTH] = {0}; static char data_r0[DAT_LENGTH]; static char data_r1[DAT_LENGTH]; -static xTaskHandle init_handle; -static xTaskHandle read_handle; -static xTaskHandle write_handle; -static xTaskHandle slave_handle; - static FFreeRTOSI2c *os_i2c_master; static FFreeRTOSI2c *os_i2c_slave; +enum +{ + I2C_MS_TEST_SUCCESS = 0, + I2C_MS_TEST_UNKNOWN = 1, + I2C_MS_SET_FAILURE = 2, + I2C_MS_WRITE_FAILURE = 3, + I2C_MS_READ_FAILURE = 4, + I2C_MS_EEPROM_DUMP_FAILURE = 5, +}; +static QueueHandle_t xQueue = NULL; + typedef struct data { boolean first_write;/*IIC首次写入,在初始化时置位,用来指示当前传输的首个字节数据是用户需要读写的地址偏移*/ u32 buff_idx;/* PC 指向的地址偏移 */ u8 buff[IO_BUF_LEN];/*虚拟内存块*/ } FI2cSlaveData; - /* Slave mode for virtual eeprom memory ,size: IO_BUF_LEN in fi2c_os.h*/ static FI2cSlaveData slave; -/** - * @name: FFreeRTOSI2cSlaveDump - * @msg: dump buffer of slave - * @return {*} - * @param {FFreeRTOSI2c} *os_i2c_p - */ -void FFreeRTOSI2cSlaveDump(FFreeRTOSI2c *os_i2c_p) -{ - FASSERT(os_i2c_p); - FASSERT(os_i2c_p->wr_semaphore != NULL); - FI2cSlaveData *slave_p = &slave; - FtDumpHexByte(slave_p->buff, IO_BUF_LEN); -} - /** * @name: FI2cSlaveCb * @msg: 从机内存操作 @@ -106,6 +105,7 @@ void FI2cOsSlaveCb(void *instance_p, void *para, u32 evt) case FI2C_EVT_SLAVE_WRITE_RECEIVED: if (slave_p->first_write) { + /*第一个传入的数据是内部偏移地址,而非待写入数据*/ slave_p->buff_idx = *val; slave_p->first_write = FALSE; } @@ -248,44 +248,38 @@ static void FI2cIntrTxAbrtcallback(void *instance, void *param) } } -static void I2cSlaveTask(void *pvParameters) +/** + * @name: EepromDump + * @msg: 打印模拟的Eeprom内部数据 + * @return {FError} + * @param {FFreeRTOSI2c} *os_i2c_read_p + */ +static FError EepromDump(FFreeRTOSI2c *os_i2c_read_p) { - const char *pcTaskName = "\r\n*****I2cSlaveTask is running...\r\n"; const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); vTaskDelay(xDelay); FError ret = FREERTOS_I2C_SUCCESS; + FI2cSlaveData *slave_p = &slave; + FASSERT(os_i2c_read_p); + FASSERT(os_i2c_read_p->wr_semaphore != NULL); - /* The FFreeRTOSI2c to use is passed in via the parameter. - Cast this to a FFreeRTOSI2c pointer. */ - FFreeRTOSI2c *os_i2c_write_p = (FFreeRTOSI2c *) pvParameters; - - vPrintf(pcTaskName); - /* 获取到信号,打印内存块 */ - FFreeRTOSI2cSlaveDump(os_i2c_write_p); - vTaskDelete(NULL); + printf("Eeprom dump: \r\n"); + /*只打印前半部分数据*/ + FtDumpHexByte(slave_p->buff, IO_BUF_LEN/2); + return ret; } - -static void I2cReadTask(void *pvParameters) +static FError I2cRead(FFreeRTOSI2c *os_i2c_read_p) { const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); vTaskDelay(xDelay); - const char *pcReadTaskName = "\r\n*****I2cReadTask is running...\r\n"; - vPrintf(pcReadTaskName); FError ret = FREERTOS_I2C_SUCCESS; - /* Master mode for send or receive data */ FFreeRTOSI2cMessage message; - /* The FFreeRTOSI2c to use is passed in via the parameter. - Cast this to a FFreeRTOSI2c pointer. */ - FFreeRTOSI2c *os_i2c_read_p = (FFreeRTOSI2c *) pvParameters; - message.slave_addr = os_i2c_read_p->i2c_device.config.slave_addr; - - /*8位地址*/ - message.mem_byte_len = 1; - message.mem_addr = 0x1;/* 地址偏移0x1的位置poll方式读取数据 */ + message.mem_byte_len = 1; /* 8位地址 */ + message.mem_addr = 0x01; /* 地址偏移0x1的位置poll方式读取数据 */ message.buf_length = DAT_LENGTH; message.buf = data_r0; message.mode = FI2C_READ_DATA_POLL; @@ -293,43 +287,46 @@ static void I2cReadTask(void *pvParameters) ret = FFreeRTOSI2cTransfer(os_i2c_read_p, &message); if (ret != FREERTOS_I2C_SUCCESS) { - vPrintf("FFreeRTOSI2cTransfer read poll task error,i2c id:%d.\r\n", os_i2c_read_p->i2c_device.config.instance_id); + FI2C_ERROR("FFreeRTOSI2cTransfer read poll task error,i2c id:%d.\r\n", os_i2c_read_p->i2c_device.config.instance_id); + return ret; } - message.mem_addr = 0x31;/* 地址偏移0x35的位置poll方式读取数据 */ + message.mem_addr = 0x31;/* 地址偏移0x31的位置poll方式读取数据 */ message.buf = data_r1; message.buf_length = DAT_LENGTH; ret = FFreeRTOSI2cTransfer(os_i2c_read_p, &message); if (ret != FREERTOS_I2C_SUCCESS) { - vPrintf("FFreeRTOSI2cTransfer read poll task error,i2c id:%d.\r\n", os_i2c_read_p->i2c_device.config.instance_id); + FI2C_ERROR("FFreeRTOSI2cTransfer read poll task error,i2c id:%d.\r\n", os_i2c_read_p->i2c_device.config.instance_id); + return ret; } - vPrintf("data_r0:\r\n"); + + for (int i = 0; i < DAT_LENGTH; i++) + { + if (data_r0[i] != data_w[i] && data_r1[i] != data_w[i]) + { + FI2C_ERROR("The read and write data is inconsistent.\r\n"); + ret = FREERTOS_I2C_INVAILD_PARAM_ERROR; + return ret; + } + } + + printf("data_r0:\r\n"); FtDumpHexByte(data_r0, DAT_LENGTH); - vPrintf("data_r1:\r\n"); + printf("data_r1:\r\n"); FtDumpHexByte(data_r1, DAT_LENGTH); - FFreeRTOSI2cDeinit(os_i2c_read_p);/*写入再读取完成后去初始化FFreeRTOSI2c主机设置*/ - printf("I2cReadTask is over.\r\n "); - vTaskDelete(NULL); + return ret; } -static void I2cWriteTask(void *pvParameters) +static FError I2cWrite(FFreeRTOSI2c *os_i2c_write_p) { - const char *pcWriteTaskName = "\r\n*****I2cWriteTask is running...\r\n"; - vPrintf(pcWriteTaskName); FError ret = FREERTOS_I2C_SUCCESS; - u8 i; /* Master mode for send or receive data */ FFreeRTOSI2cMessage message; - - /* The FFreeRTOSI2c to use is passed in via the parameter. - Cast this to a FFreeRTOSI2c pointer. */ - FFreeRTOSI2c *os_i2c_write_p = (FFreeRTOSI2c *) pvParameters; - message.slave_addr = os_i2c_write_p->i2c_device.config.slave_addr; - for (i = 0; i < DAT_LENGTH; i++) + for (u8 i = 0; i < DAT_LENGTH; i++) { - data_w[i] = i ; + data_w[i] = i + 1; } /*8位地址*/ message.mem_byte_len = 1; @@ -340,22 +337,24 @@ static void I2cWriteTask(void *pvParameters) ret = FFreeRTOSI2cTransfer(os_i2c_write_p, &message); if (ret != FREERTOS_I2C_SUCCESS) { - vPrintf("FFreeRTOSI2cTransfer write poll task error,i2c id:%d.\r\n", os_i2c_write_p->i2c_device.config.instance_id); + FI2C_ERROR("FFreeRTOSI2cTransfer write poll task error,i2c id:%d.\r\n", os_i2c_write_p->i2c_device.config.instance_id); + return ret; } - message.mem_addr = 0x31;/* 地址偏移0x35的位置poll方式写入数据 */ + message.mem_addr = 0x31;/* 地址偏移0x31的位置poll方式写入数据 */ ret = FFreeRTOSI2cTransfer(os_i2c_write_p, &message); if (ret != FREERTOS_I2C_SUCCESS) { - vPrintf("FFreeRTOSI2cTransfer write poll task error,i2c id:%d.\r\n", os_i2c_write_p->i2c_device.config.instance_id); + FI2C_ERROR("FFreeRTOSI2cTransfer write poll task error,i2c id:%d.\r\n", os_i2c_write_p->i2c_device.config.instance_id); + return ret; } - printf("I2cWriteTask is over.\r\n "); - vTaskDelete(NULL); + + return ret; } static FError FFreeRTOSI2cInitSet(uint32_t id, uint32_t work_mode, uint32_t slave_address) { - FError err; + FError ret = FREERTOS_I2C_SUCCESS; FIOPadSetMioMux(id); /* init i2c controller */ @@ -375,11 +374,11 @@ static FError FFreeRTOSI2cInitSet(uint32_t id, uint32_t work_mode, uint32_t slav /* register intr callback */ InterruptInstall(os_i2c_slave->i2c_device.config.irq_num, FI2cSlaveIntrHandler, &os_i2c_slave->i2c_device, "fi2cslave"); /* slave mode intr set,must set before master data come in. */ - err = FI2cSlaveSetupIntr(&os_i2c_slave->i2c_device); - if (err != FREERTOS_I2C_SUCCESS) + ret = FI2cSlaveSetupIntr(&os_i2c_slave->i2c_device); + if (ret != FREERTOS_I2C_SUCCESS) { - vPrintf("I2c slave intr init failed.\r\n"); - return FREERTOS_I2C_INVAL_STATE_ERROR; + FI2C_ERROR("I2c slave intr init failed.\r\n"); + return ret; } FI2cSlaveData *slave_p = &slave; memset(slave_p, 0, sizeof(*slave_p)); @@ -390,57 +389,68 @@ static FError FFreeRTOSI2cInitSet(uint32_t id, uint32_t work_mode, uint32_t slav FI2cSlaveRegisterIntrHandler(&os_i2c_slave->i2c_device, FI2C_EVT_SLAVE_STOP, FI2cOsSlaveStop); FI2cSlaveRegisterIntrHandler(&os_i2c_slave->i2c_device, FI2C_EVT_SLAVE_WRITE_REQUESTED, FI2cOsSlaveWriteRequest); } - return FREERTOS_I2C_SUCCESS; + + return ret; } -static void I2cInitTask(void *pvParameters) +static void FFreeRTOSI2cDelete(void) { - FError err; - BaseType_t xReturn = pdPASS; + FIOMuxDeInit(); - taskENTER_CRITICAL(); //进入临界区 - /* init mio fuction */ + FFreeRTOSI2cDeinit(os_i2c_master); + FFreeRTOSI2cDeinit(os_i2c_slave); +} + +static void FFreeRTOSI2cLoopbackTask(void *pvParameters) +{ + FError ret; + BaseType_t xReturn = pdPASS; + int task_res = I2C_MS_TEST_SUCCESS; FIOMuxInit(); - - err = FFreeRTOSI2cInitSet(FMIO1_ID, FI2C_MASTER, MASTER_SLAVE_ADDR); - if (err != FREERTOS_I2C_SUCCESS) + + ret = FFreeRTOSI2cInitSet(I2C_MS_TEST_MASTER_DEVICE, FI2C_MASTER, MASTER_SLAVE_ADDR); + if (ret != FREERTOS_I2C_SUCCESS) { - vPrintf("I2c FFreeRTOSI2cInitSet failed.\r\n"); - return; + FI2C_ERROR("I2c FFreeRTOSI2cInitSet failed.\r\n"); + task_res = I2C_MS_SET_FAILURE; + goto task_exit; } - err = FFreeRTOSI2cInitSet(FMIO2_ID, FI2C_SLAVE, MASTER_SLAVE_ADDR); - if (err != FREERTOS_I2C_SUCCESS) + ret = FFreeRTOSI2cInitSet(I2C_MS_TEST_SLAVE_DEVICE, FI2C_SLAVE, MASTER_SLAVE_ADDR); + if (ret != FREERTOS_I2C_SUCCESS) { - vPrintf("I2c FFreeRTOSI2cInitSet failed.\r\n"); - return; + FI2C_ERROR("I2c FFreeRTOSI2cInitSet failed.\r\n"); + task_res = I2C_MS_SET_FAILURE; + goto task_exit; } - xReturn = xTaskCreate((TaskFunction_t)I2cReadTask, /* 任务入口函数 */ - (const char *)"I2cReadTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - (void *)os_i2c_master,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 2, /* 任务的优先级 */ - (TaskHandle_t *)&read_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "I2cReadTask creation is failed."); + ret = I2cWrite(os_i2c_master); + if (ret != FREERTOS_I2C_SUCCESS) + { + FI2C_ERROR("I2cWrite failed.\r\n"); + task_res = I2C_MS_WRITE_FAILURE; + goto task_exit; + } - xReturn = xTaskCreate((TaskFunction_t)I2cWriteTask, /* 任务入口函数 */ - (const char *)"I2cWriteTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - (void *)os_i2c_master,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ - (TaskHandle_t *)&write_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "I2cWriteTask creation is failed."); + ret = I2cRead(os_i2c_master); + if (ret != FREERTOS_I2C_SUCCESS) + { + FI2C_ERROR("I2cRead failed.\r\n"); + task_res = I2C_MS_READ_FAILURE; + goto task_exit; + } - xReturn = xTaskCreate((TaskFunction_t)I2cSlaveTask, /* 任务入口函数 */ - (const char *)"I2cSlaveTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - (void *)os_i2c_slave,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 3, /* 任务的优先级 */ - (TaskHandle_t *)&slave_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "I2cSlaveTask creation is failed."); + ret = EepromDump(os_i2c_slave); + if (ret != FREERTOS_I2C_SUCCESS) + { + FI2C_ERROR("EepromDump failed.\r\n"); + task_res = I2C_MS_EEPROM_DUMP_FAILURE; + goto task_exit; + } + +task_exit: + xQueueSend(xQueue, &task_res, 0); - taskEXIT_CRITICAL(); //退出临界区 vTaskDelete(NULL); } @@ -448,21 +458,43 @@ BaseType_t FFreeRTOSI2cLoopbackCreate(void) { BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ BaseType_t xTimerStarted = pdPASS; + int task_res = I2C_MS_TEST_UNKNOWN; - taskENTER_CRITICAL(); //进入临界区 + xQueue = xQueueCreate(1, sizeof(int)); + if (xQueue == NULL) + { + printf("xQueue create failed.\r\n"); + goto exit; + } - xReturn = xTaskCreate((TaskFunction_t)I2cInitTask, /* 任务入口函数 */ - (const char *)"I2cInitTask",/* 任务名字 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSI2cLoopbackTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSI2cLoopbackTask",/* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ (void *)NULL,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ - (TaskHandle_t *)&init_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "I2cInitTask creation is failed."); - - taskEXIT_CRITICAL(); //退出临界区 - printf("I2c task is created successfully.\r\n"); - vTaskDelay(TASK_DELAY_MS*3); - return xReturn; + (UBaseType_t)I2C_MS_TEST_TASK_PRIORITY, /* 任务的优先级 */ + NULL); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "FFreeRTOSI2cLoopbackTask creation is failed."); + + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FI2C_ERROR("xQueue receive timeout.\r\n"); + goto exit; + } + +exit: + vQueueDelete(xQueue); + FFreeRTOSI2cDelete(); + if (task_res != I2C_MS_TEST_SUCCESS) + { + printf("%s@%d: I2C ms simulate eeprom example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return pdFAIL; + } + else + { + printf("%s@%d: I2C ms simulate eeprom example [success].\r\n", __func__, __LINE__); + return pdTRUE; + } } diff --git a/example/peripheral/i2c/src/i2c_rtc_example.c b/example/peripheral/i2c/src/i2c_rtc_example.c index 9f3da3f54f567b14f55efe93d340834e8809abc5..194f937e48e1c07f06411b2bfc186aaba6368465 100644 --- a/example/peripheral/i2c/src/i2c_rtc_example.c +++ b/example/peripheral/i2c/src/i2c_rtc_example.c @@ -20,73 +20,73 @@ * Ver    Who         Date          Changes * -----  ------      --------     -------------------------------------- * 1.0 liushengming 2022/11/25 init commit - * 1.0 liushengming 2023/09/25 rtc commit + * 1.0 liushengming 2023/09/25 rtc commit + * 1.1 zhangyan 2024/4/18 add no letter shell mode, adapt to auto-test system */ #include #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "fi2c.h" -#include "fi2c_hw.h" #include "fi2c_os.h" -#include "timers.h" -#include "fcpu_info.h" #include "i2c_example.h" -#include "fparameters.h" #include "fio_mux.h" #include "sdkconfig.h" #include "fdebug.h" #include "ftypes.h" #include "finterrupt.h" -#if defined(CONFIG_E2000D_DEMO_BOARD) || defined(CONFIG_E2000Q_DEMO_BOARD) || defined(CONFIG_FIREFLY_DEMO_BOARD) +#define FI2C_DEBUG_TAG "I2C_RTC_TEST" +#define FI2C_ERROR(format, ...) FT_DEBUG_PRINT_E(FI2C_DEBUG_TAG, format, ##__VA_ARGS__) +#define FI2C_WARN(format, ...) FT_DEBUG_PRINT_W(FI2C_DEBUG_TAG, format, ##__VA_ARGS__) +#define FI2C_INFO(format, ...) FT_DEBUG_PRINT_I(FI2C_DEBUG_TAG, format, ##__VA_ARGS__) +#define FI2C_DEBUG(format, ...) FT_DEBUG_PRINT_D(FI2C_DEBUG_TAG, format, ##__VA_ARGS__) + +#if defined(CONFIG_E2000D_DEMO_BOARD) || defined(CONFIG_E2000Q_DEMO_BOARD) #define DS_1339_MIO FMIO9_ID -#else -#define DS_1339_MIO FMIO0_ID #endif /* * RTC register addresses */ -#define DS1339_SEC_REG 0x0 -#define DS1339_MIN_REG 0x1 -#define DS1339_HOUR_REG 0x2 -#define DS1339_DAY_REG 0x3 -#define DS1339_DATE_REG 0x4 -#define DS1339_MONTH_REG 0x5 -#define DS1339_YEAR_REG 0x6 +#define DS1339_SEC_REG 0x0 +#define DS1339_MIN_REG 0x1 +#define DS1339_HOUR_REG 0x2 +#define DS1339_DAY_REG 0x3 +#define DS1339_DATE_REG 0x4 +#define DS1339_MONTH_REG 0x5 +#define DS1339_YEAR_REG 0x6 -#define BCD_TO_BIN(bcd) (( ((((bcd)&0xf0)>>4)*10) + ((bcd)&0xf) ) & 0xff) -#define BIN_TO_BCD(bin) (( (((bin)/10)<<4) + ((bin)%10) ) & 0xff) +#define BCD_TO_BIN(bcd) ((((((bcd) & 0xf0) >> 4) * 10) + ((bcd) & 0xf)) & 0xff) +#define BIN_TO_BCD(bin) (((((bin) / 10) << 4) + ((bin) % 10)) & 0xff) /* write and read task delay in milliseconds */ -#define TASK_DELAY_MS 1000UL - -/* rtc address */ - -#define RTC_ADDR 0x68 - -#define DAT_LENGTH 15 - +#define TASK_DELAY_MS 1000UL +#define I2C_RTC_TEST_TASK_PRIORITY 3 +#define RTC_ADDR 0x68 /* rtc address */ +#define DAT_LENGTH 15 static char data_r0[DAT_LENGTH]; - -static xTaskHandle init_handle; -static xTaskHandle read_handle; -static xTaskHandle write_handle; - - +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) +enum +{ + I2C_RTC_TEST_SUCCESS = 0, + I2C_RTC_TEST_UNKNOWN = 1, + I2C_RTC_SET_FAILURE = 2, + I2C_RTC_WRITE_FAILURE = 3, + I2C_RTC_READ_FAILURE = 4, +}; +static QueueHandle_t xQueue = NULL; static FFreeRTOSI2c *os_i2c_master; typedef struct { - u16 year; /* year */ - u8 month; /* month */ - u8 day_of_month; /* day of month */ - u8 day_of_week; /* day of week */ - u8 hour; /* hour */ - u8 minute; /* minute */ - u8 second; /* second */ + u16 year; /* year */ + u8 month; /* month */ + u8 day_of_month; /* day of month */ + u8 day_of_week; /* day of week */ + u8 hour; /* hour */ + u8 minute; /* minute */ + u8 second; /* second */ } FRtcDateTimer; static FError DsRtcDateCheck(FRtcDateTimer *rtc_time) @@ -145,8 +145,8 @@ static void FI2cIntrTxDonecallback(void *instance, void *param) { BaseType_t x_result = pdFALSE; BaseType_t xhigher_priority_task_woken = pdFALSE; - FI2c *instance_p = (FI2c *)instance; + x_result = xEventGroupSetBitsFromISR(os_i2c_master[instance_p->config.instance_id].trx_event, RTOS_I2C_WRITE_DONE, &xhigher_priority_task_woken); if (x_result != pdFAIL) { @@ -163,8 +163,8 @@ static void FI2cIntrRxDonecallback(void *instance, void *param) { BaseType_t x_result = pdFALSE; BaseType_t xhigher_priority_task_woken = pdFALSE; - FI2c *instance_p = (FI2c *)instance; + x_result = xEventGroupSetBitsFromISR(os_i2c_master[instance_p->config.instance_id].trx_event, RTOS_I2C_READ_DONE, &xhigher_priority_task_woken); if (x_result != pdFAIL) { @@ -181,8 +181,8 @@ static void FI2cIntrTxAbrtcallback(void *instance, void *param) { BaseType_t x_result = pdFALSE; BaseType_t xhigher_priority_task_woken = pdFALSE; - FI2c *instance_p = (FI2c *)instance; + x_result = xEventGroupSetBitsFromISR(os_i2c_master[instance_p->config.instance_id].trx_event, RTOS_I2C_TRANS_ABORTED, &xhigher_priority_task_woken); if (x_result != pdFAIL) { @@ -190,24 +190,21 @@ static void FI2cIntrTxAbrtcallback(void *instance, void *param) } } -static void I2cReadTask(void *pvParameters) +static FError I2cRead(FFreeRTOSI2c *os_i2c_read_p) { const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); vTaskDelay(xDelay); - const char *pcReadTaskName = "\r\n*****I2cReadTask is running...\r\n"; + const char *pcReadTaskName = "\r\n*****I2cRead is running...\r\n"; vPrintf(pcReadTaskName); FError ret = FREERTOS_I2C_SUCCESS; - /* Master mode for send or receive data */ FFreeRTOSI2cMessage message; /* The FFreeRTOSI2c to use is passed in via the parameter. Cast this to a FFreeRTOSI2c pointer. */ - FFreeRTOSI2c *os_i2c_read_p = (FFreeRTOSI2c *) pvParameters; - message.slave_addr = os_i2c_read_p->i2c_device.config.slave_addr; message.mem_byte_len = 1; - message.mem_addr = 0x0;/* 地址偏移0x0的位置poll方式读取数据 */ + message.mem_addr = 0x0; /* 地址偏移0x0的位置poll方式读取数据 */ message.buf_length = 7; message.buf = data_r0; message.mode = FI2C_READ_DATA_POLL; @@ -215,7 +212,8 @@ static void I2cReadTask(void *pvParameters) ret = FFreeRTOSI2cTransfer(os_i2c_read_p, &message); if (ret != FREERTOS_I2C_SUCCESS) { - vPrintf("FFreeRTOSI2cTransfer read poll task error,i2c id:%d.\r\n", os_i2c_read_p->i2c_device.config.instance_id); + FI2C_ERROR("FFreeRTOSI2cTransfer read poll task error,i2c id:%d.\r\n", os_i2c_read_p->i2c_device.config.instance_id); + return ret; } u16 year; if (data_r0[5] & 0x80) @@ -233,47 +231,40 @@ static void I2cReadTask(void *pvParameters) BCD_TO_BIN((data_r0[3] - 1) & 0x7), BCD_TO_BIN(data_r0[2] & 0x3F), BCD_TO_BIN(data_r0[1] & 0x7F), - BCD_TO_BIN(data_r0[0] & 0x7F) - ); - vTaskDelay(xDelay); - FFreeRTOSI2cDeinit(os_i2c_read_p);/*写入再读取完成后去初始化FFreeRTOSI2c主机设置*/ - /* deinit iomux */ - FIOMuxDeInit(); - printf("I2cReadTask is over.\r\n "); - vTaskDelete(NULL); + BCD_TO_BIN(data_r0[0] & 0x7F)); + + return ret; } -static void I2cWriteTask(void *pvParameters) +static FError I2cWrite(FFreeRTOSI2c *os_i2c_write_p) { - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - vTaskDelay(xDelay); - const char *pcWriteTaskName = "\r\n*****I2cWriteTask is running...\r\n"; + int task_res = 0; + const char *pcWriteTaskName = "\r\n*****I2cWrite is running...\r\n"; vPrintf(pcWriteTaskName); FError ret = FREERTOS_I2C_SUCCESS; - u8 i,century; + u8 i, century; u8 data_buf[7] = {0}; /* Master mode for send or receive data */ FFreeRTOSI2cMessage message; /* The FFreeRTOSI2c to use is passed in via the parameter. Cast this to a FFreeRTOSI2c pointer. */ - FFreeRTOSI2c *os_i2c_write_p = (FFreeRTOSI2c *) pvParameters; message.slave_addr = os_i2c_write_p->i2c_device.config.slave_addr; - FRtcDateTimer date_time = {2023, 9, 25, 1, 20, 13, 30}; + FRtcDateTimer date_time = {2024, 4, 26, 5, 11, 22, 30}; printf("Set:year: %d, month: %d, day: %d,week: %d, hour: %d, minute: %d, second: %d\r\n", - date_time.year, - date_time.month, - date_time.day_of_month, - date_time.day_of_week, - date_time.hour, - date_time.minute, - date_time.second); + date_time.year, + date_time.month, + date_time.day_of_month, + date_time.day_of_week, + date_time.hour, + date_time.minute, + date_time.second); ret = DsRtcDateCheck(&date_time); if (FREERTOS_I2C_SUCCESS != ret) { - vPrintf("Time data param error.\r\n"); - return; + FI2C_ERROR("Time data param error.\r\n"); + return ret; } data_buf[0] = BIN_TO_BCD(date_time.second); @@ -301,23 +292,24 @@ static void I2cWriteTask(void *pvParameters) message.mem_byte_len = 1; message.buf = &data_buf; message.buf_length = sizeof(data_buf); - message.mem_addr = 0x0;/* 地址偏移0x0的位置poll方式写入数据 */ + message.mem_addr = 0x0; /* 地址偏移0x0的位置poll方式写入数据 */ message.mode = FI2C_WRITE_DATA_POLL; ret = FFreeRTOSI2cTransfer(os_i2c_write_p, &message); if (ret != FREERTOS_I2C_SUCCESS) { - vPrintf("FFreeRTOSI2cTransfer write poll task error,i2c id:%d.\r\n", os_i2c_write_p->i2c_device.config.instance_id); + FI2C_ERROR("FFreeRTOSI2cTransfer write poll task error,i2c id:%d.\r\n", os_i2c_write_p->i2c_device.config.instance_id); + return ret; } - printf("I2cWriteTask is over.\r\n "); - vTaskDelete(NULL); + + return ret; } static FError FFreeRTOSI2cInitSet(uint32_t id, uint32_t work_mode, uint32_t slave_address) { - FError err; + FError ret = FREERTOS_I2C_SUCCESS; /* init iomux */ FIOMuxInit(); - + FIOPadSetMioMux(id); /* init i2c controller */ if (work_mode == FI2C_MASTER) /* 主机初始化默认使用poll模式 */ @@ -332,67 +324,95 @@ static FError FFreeRTOSI2cInitSet(uint32_t id, uint32_t work_mode, uint32_t slav } else { - printf("error_work_mode!\r\n"); - return FREERTOS_I2C_INVAILD_PARAM_ERROR; + FI2C_ERROR("error_work_mode!\r\n"); + ret = FREERTOS_I2C_INVAILD_PARAM_ERROR; } - return FREERTOS_I2C_SUCCESS; + + return ret; } -static void I2cInitTask(void *pvParameters) +static void FFreeRTOSI2cDelete(void) { - FError err; - BaseType_t xReturn = pdPASS; + FIOMuxDeInit(); + + FFreeRTOSI2cDeinit(os_i2c_master); +} - taskENTER_CRITICAL(); //进入临界区 +static void FFreeRTOSI2cRtcTask(void *pvParameters) +{ + FError ret; + int task_res = I2C_RTC_TEST_SUCCESS; + + ret = FFreeRTOSI2cInitSet(DS_1339_MIO, FI2C_MASTER, RTC_ADDR); + if (ret != FREERTOS_I2C_SUCCESS) + { + FI2C_ERROR("I2c FFreeRTOSI2cInitSet failed.\r\n"); + task_res = I2C_RTC_SET_FAILURE; + goto task_exit; + } - err = FFreeRTOSI2cInitSet(DS_1339_MIO, FI2C_MASTER, RTC_ADDR); - if (err != FREERTOS_I2C_SUCCESS) + ret = I2cWrite(os_i2c_master); + if (ret != FREERTOS_I2C_SUCCESS) { - vPrintf("I2c FFreeRTOSI2cInitSet failed.\r\n"); - return; + FI2C_ERROR("I2cWrite failed.\r\n"); + task_res = I2C_RTC_WRITE_FAILURE; + goto task_exit; } - - xReturn = xTaskCreate((TaskFunction_t)I2cReadTask, /* 任务入口函数 */ - (const char *)"I2cReadTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - (void *)os_i2c_master,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 2, /* 任务的优先级 */ - (TaskHandle_t *)&read_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "I2cReadTask creation is failed."); - - xReturn = xTaskCreate((TaskFunction_t)I2cWriteTask, /* 任务入口函数 */ - (const char *)"I2cWriteTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - (void *)os_i2c_master,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ - (TaskHandle_t *)&write_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "I2cWriteTask creation is failed."); - - taskEXIT_CRITICAL(); //退出临界区 + for (int i = 0; i < 2; i++) + { + ret = I2cRead(os_i2c_master); + if (ret != FREERTOS_I2C_SUCCESS) + { + FI2C_ERROR("I2cRead failed.\r\n"); + task_res = I2C_RTC_READ_FAILURE; + goto task_exit; + } + } + +task_exit: + xQueueSend(xQueue, &task_res, 0); + vTaskDelete(NULL); } BaseType_t FFreeRTOSI2cRtcCreate(void) { - BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ BaseType_t xTimerStarted = pdPASS; + int task_res = I2C_RTC_TEST_UNKNOWN; - taskENTER_CRITICAL(); //进入临界区 - - xReturn = xTaskCreate((TaskFunction_t)I2cInitTask, /* 任务入口函数 */ - (const char *)"I2cInitTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - (void *)NULL,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ - (TaskHandle_t *)&init_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "I2cInitTask creation is failed."); + xQueue = xQueueCreate(1, sizeof(int)); + if (xQueue == NULL) + { + FI2C_ERROR("xQueue create failed.\r\n"); + goto exit; + } + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSI2cRtcTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSI2cRtcTask", /* 任务名字 */ + (uint16_t)1024, /* 任务栈大小 */ + (void *)NULL, /* 任务入口函数参数 */ + (UBaseType_t)I2C_RTC_TEST_TASK_PRIORITY, /* 任务的优先级 */ + NULL); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "FFreeRTOSI2cRtcTask creation is failed."); + + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FI2C_ERROR("xQueue receive timeout.\r\n"); + goto exit; + } - taskEXIT_CRITICAL(); //退出临界区 - printf("I2c task is created successfully.\r\n"); - vTaskDelay(TASK_DELAY_MS*3); - return xReturn; +exit: + vQueueDelete(xQueue); + FFreeRTOSI2cDelete(); + if (task_res != I2C_RTC_TEST_SUCCESS) + { + printf("%s@%d: I2C rtc example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return pdFAIL; + } + else + { + printf("%s@%d: I2C rtc indirect example [success].\r\n", __func__, __LINE__); + return pdTRUE; + } } - - - - diff --git a/example/peripheral/i2s/inc/i2s_example.h b/example/peripheral/i2s/inc/i2s_example.h index 013e71a94be16b3c225bc78315fd2ea1d7b83ab7..b6649dd656892e72fac5b2439493b6ea3a65d7c0 100644 --- a/example/peripheral/i2s/inc/i2s_example.h +++ b/example/peripheral/i2s/inc/i2s_example.h @@ -26,16 +26,14 @@ #ifndef I2S_EXAMPLE_H #define I2S_EXAMPLE_H -#include "fi2s_os.h" +#include "FreeRTOS.h" + #ifdef __cplusplus extern "C" { #endif /*init i2s task*/ -BaseType_t FFreeRTOSI2sInitCreate(void); - -/*deinit i2s task*/ -BaseType_t FFreeRTOSI2sDeInitCreate(void); +BaseType_t FFreeRTOSRunI2sExample(void); #ifdef __cplusplus } diff --git a/example/peripheral/i2s/main.c b/example/peripheral/i2s/main.c index 5bf291c5d850843883baf3c448a02e4784b2f3ae..9c9ba8cc546cd10c476b4928b1fd000e8460683b 100644 --- a/example/peripheral/i2s/main.c +++ b/example/peripheral/i2s/main.c @@ -20,28 +20,62 @@ * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 wzq 2024/02/29 first commit + * 1.1 wzq 2024/04/25 add shell support */ +#include + +#include "FreeRTOS.h" + +#include "sdkconfig.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include +#else +#include "task.h" #include "i2s_example.h" +#define I2S_EXAMPLE_TASK_PRIORITY 2 + +void I2sExampleTaskEntry() +{ + /* example functions */ + FFreeRTOSRunI2sExample(); + + /* end flag */ + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif + int main(void) { - BaseType_t ret; + BaseType_t ret = pdPASS; +#ifdef CONFIG_USE_LETTER_SHELL ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)I2sExampleTaskEntry, /* 任务入口函数 */ + (const char *)"I2sExampleTaskEntry", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)I2S_EXAMPLE_TASK_PRIORITY, /* 任务优先级 */ + NULL); /* 任务句柄 */ +#endif + if (ret != pdPASS) { goto FAIL_EXIT; } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + /* 启动任务,开启调度 */ + vTaskStartScheduler(); while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("Failed,the ret value is 0x%x. \r\n", ret); + printf("I2s example failed in main.c, the ret value is 0x%x. \r\n", ret); return 0; -} +} \ No newline at end of file diff --git a/example/peripheral/i2s/makefile b/example/peripheral/i2s/makefile index 13c14898d0f8ad5159f3e5baa6067deda58349eb..8cdbb131737371bf472dd0695f73ceba32b2c1a4 100644 --- a/example/peripheral/i2s/makefile +++ b/example/peripheral/i2s/makefile @@ -8,7 +8,6 @@ BOOT_IMG_NAME ?= freertos USER_CSRC := main.c USER_CSRC += $(wildcard src/*.c) -USER_CSRC += $(wildcard ../common/*.c) USER_ASRC := USER_CXXSRC := diff --git a/example/peripheral/i2s/src/cmd_i2s.c b/example/peripheral/i2s/src/cmd_i2s.c index e8d9b79586760d0b69c977338357b7d39538569b..bbccb5dfb5bfe374ca655cefd5c1fc17a91eddec 100644 --- a/example/peripheral/i2s/src/cmd_i2s.c +++ b/example/peripheral/i2s/src/cmd_i2s.c @@ -20,56 +20,49 @@ * Ver    Who         Date          Changes * -----  ------      --------     -------------------------------------- * 1.0 Wangzq 2024/02/29 first commit + * 1.1 wzq 2024/04/25 add shell support */ /***************************** Include Files *********************************/ #include #include #include "strto.h" #include "sdkconfig.h" + #include "FreeRTOS.h" -#include "shell.h" -#include "fi2s_os.h" -#include "i2s_example.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "../src/shell.h" +#include "i2s_example.h" /************************** Function Prototypes ******************************/ static void FI2sExampleUsage() { printf("Usage:\r\n"); - printf(" i2s init\r\n"); - printf(" -- init the i2s and set some config.\r\n"); - printf(" i2s deinit\r\n"); - printf(" -- deinit the i2s .\r\n"); + printf("i2s example\r\n"); + printf("-- demo to test i2s transfer.\r\n"); } static int I2sCmdEntry(int argc, char *argv[]) { int ret = 0; + if (argc < 2) { FI2sExampleUsage(); return -1; } - else if (!strcmp(argv[1], "init")) + else if (!strcmp(argv[1], "example")) { - ret = FFreeRTOSI2sInitCreate(); - if (ret != pdPASS) - { - printf("FFreeRTOSI2sInitCreate error :0x%x!\n",ret); - return ret; - } - } - else if (!strcmp(argv[1], "deinit")) - { - ret = FFreeRTOSI2sDeInitCreate(); - if (ret != pdPASS) - { - printf("FFreeRTOSI2sDeInitCreate error :0x%x!\n",ret); - return ret; - } + ret = FFreeRTOSRunI2sExample(); + + return ret; + } + return ret; } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), i2s, I2sCmdEntry, test freertos i2s driver); + +#endif /* CONFIG_USE_LETTER_SHELL */ \ No newline at end of file diff --git a/example/peripheral/i2s/src/i2s_example.c b/example/peripheral/i2s/src/i2s_example.c index d76bb3394b1806ac23ce4e4b3321c664369efcd5..9c2d234cae5d806216cfe41310fb0f64bdd7eefd 100644 --- a/example/peripheral/i2s/src/i2s_example.c +++ b/example/peripheral/i2s/src/i2s_example.c @@ -19,19 +19,18 @@ * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- - * 1.0 Wangzq 2024/02/29 first commit + * 1.0 Wangzq 2024/02/29 first commit + * 2.0 Wangzq 2024/4/22 add no letter shell mode, adapt to auto-test system */ +#include #include -#include "FreeRTOSConfig.h" + #include "FreeRTOS.h" #include "task.h" -#include "timers.h" -#include "fcpu_info.h" + +#include "fdebug.h" #include "fio_mux.h" -#include "fassert.h" -#include"fparameters.h" -#include"fparameters_comm.h" #include "fmemory_pool.h" #include "ferror_code.h" #include "fcache.h" @@ -39,74 +38,57 @@ #include "fi2s_os.h" #include "fddma_os.h" #include "fddma.h" -#include "fddma_hw.h" #include "fddma_bdl.h" #include "fes8336.h" #include "fi2s.h" #include "fi2s_hw.h" /************************** Constant Definitions *****************************/ -/* write and read task handle */ -static xTaskHandle i2s_init_handle; -static xTaskHandle i2s_deinit_handle; -static xTaskHandle i2s_Trans_handle; -static xTaskHandle i2s_receive_handle; -static TimerHandle_t exit_timer = NULL; -static QueueHandle_t sync = NULL; - static FFreeRTOSI2s *os_i2s = NULL; static FFreeRTOSDdma *ddma = NULL; static FFreeRTOSDdmaConfig ddma_config; static FDdmaChanIndex rx_chan_id = FDDMA_CHAN_1; static FDdmaChanIndex tx_chan_id = FDDMA_CHAN_0; static EventGroupHandle_t chan_evt = NULL; -static FFreeRTOSRequest rx_tx_request = {0}; -static FDdmaBdlDesc *bdl_desc_list_g; +static FFreeRTOSRequest rx_request = {0}; +static FFreeRTOSRequest tx_request = {0}; static FMemp memp; static u8 memp_buf[SZ_4M] = {0}; -static u32 trans_num = 0; /*已经传输完成的BDL数量*/ -#define CHAN_REQ_DONE(chan) (0x1 << chan) /* if signal, chan req finished */ -/************************** user config *****************************/ -static FDdmaBdlDescConfig bdl_desc_config[4096];/*bdl_desc_config []根据TX_RX_BUF_LEN设置*/ -static u32 per_buffer = 16384; -#define TX_RX_BUF_LEN 4096* 16384 -static u32 rx_buf = 0xa0000000; -static u8 tx_buf[TX_RX_BUF_LEN] __attribute__((aligned(FDDMA_DDR_ADDR_ALIGMENT))) = {0}; -static FI2sData i2s_config = +static boolean is_running = FALSE; +static QueueHandle_t xQueue = NULL; +#define CHAN_REQ_DONE(chan) (0x1 << chan) /* if signal, chan req finished */ +#define I2S_TEST_TASK_PRIORITY 3 +/**************************** Type Definitions *******************************/ +enum { - .word_length = FI2S_WORLD_LENGTH_16, - .data_length = 16, - .sample_rate = FI2S_SAMPLE_RATE_CD, + I2S_TRANS_TEST_SUCCESS = 0, + I2S_TRANS_TEST_UNKNOWN = 1, + I2S_INIT_ERROR = 2, + I2S_RECEIVE_ERROR = 3, + I2S_PLAYBACK_ERROR = 4, }; +/************************** user config *****************************/ +static FDdmaBdlDescConfig bdl_desc_config[100];/*bdl_desc_config []根据TX_RX_BUF_LEN设置,随buffer数更改*/ +static FDdmaBdlDesc *bdl_desc_list_g; +#define per_buffer 16384/*录制时每个buffer的大小,单位字节*/ +#define TX_RX_BUF_LEN 100* 16384/*录制时总buffer的大小,一共10个buff,单位字节*/ +static u32 data_buf = 0xa0000000; /***************** Macros (Inline Functions) Definitions *********************/ -#define FI2S_DEBUG_TAG "FI2S-OS" +#define FI2S_DEBUG_TAG "FI2S-TRANS" #define FI2S_ERROR(format, ...) FT_DEBUG_PRINT_E(FI2S_DEBUG_TAG, format, ##__VA_ARGS__) #define FI2S_WARN(format, ...) FT_DEBUG_PRINT_W(FI2S_DEBUG_TAG, format, ##__VA_ARGS__) #define FI2S_INFO(format, ...) FT_DEBUG_PRINT_I(FI2S_DEBUG_TAG, format, ##__VA_ARGS__) #define FI2S_DEBUG(format, ...) FT_DEBUG_PRINT_D(FI2S_DEBUG_TAG, format, ##__VA_ARGS__) /************************** Function Prototypes ******************************/ -static void FFreeRTOSI2sDeinitTask(void *args) +static void FFreeRTOSI2sDeinit(void) { - FError err = FT_SUCCESS; - - if (i2s_init_handle) /* stop and delete init task */ - { - vTaskDelete(i2s_init_handle); - i2s_init_handle = NULL; - } - if (i2s_Trans_handle) /* stop and delete send task */ - { - vTaskDelete(i2s_Trans_handle); - i2s_Trans_handle = NULL; - } - if (i2s_receive_handle) /* stop and delete recv task */ - { - vTaskDelete(i2s_receive_handle); - i2s_receive_handle = NULL; - } + printf("Exiting...\r\n"); + /* deinit iomux */ + FIOMuxDeInit(); + FError ret = TRUE; if (ddma) { if (FT_SUCCESS != FFreeRTOSDdmaRevokeChannel(ddma, rx_chan_id)) @@ -117,8 +99,8 @@ static void FFreeRTOSI2sDeinitTask(void *args) { FI2S_ERROR("Delete TX channel failed."); } - err = FFreeRTOSDdmaDeinit(ddma); - if (FT_SUCCESS != err) + ret = FFreeRTOSDdmaDeinit(ddma); + if (FT_SUCCESS != ret) { FI2S_ERROR("deinit ddma failed."); } @@ -126,8 +108,8 @@ static void FFreeRTOSI2sDeinitTask(void *args) } if (os_i2s) { - err = FFreeRTOSI2SDeinit(os_i2s); - if (FT_SUCCESS != err) + ret = FFreeRTOSI2SDeinit(os_i2s); + if (FT_SUCCESS != ret) { FI2S_ERROR("deinit i2s failed."); } @@ -138,11 +120,7 @@ static void FFreeRTOSI2sDeinitTask(void *args) vEventGroupDelete(chan_evt); chan_evt = NULL; } - if (sync) - { - vQueueDelete(sync); - sync = NULL; - } + is_running = FALSE; FMempFree(&memp, bdl_desc_list_g); FI2S_DEBUG("exit all task and deinit."); } @@ -168,45 +146,17 @@ static void DdmaI2sAckDMADone(FDdmaChanIrq *const chan_irq_info_p, void *arg) return; } - -static inline boolean FFreeRTOSI2sDdmaGiveSync() -{ - boolean data = TRUE; - FASSERT_MSG((NULL != sync), "Sync not exists."); - if (pdFALSE == xQueueSend(sync, &data, portMAX_DELAY)) - { - FI2S_ERROR("Failed to give locker."); - return FALSE; - } - return TRUE; -} - -static inline void FFreeRTOSI2sDdmTakeSync() -{ - boolean data = FALSE; - FASSERT_MSG((NULL != sync), "Sync not exists."); - if (pdFALSE == xQueueReceive(sync, &data, portMAX_DELAY)) - { - FI2S_ERROR("Failed to give locker."); - } - return; -} - -static boolean FFreeRTOSI2sWaitDmaEnd(void) +static FError I2sWaitTransferDone(void) { - boolean ok = TRUE; + boolean ret = TRUE; EventBits_t ev; + static u32 wait_timeout = pdMS_TO_TICKS(100000UL);/*等待超时时间,单位ms,请确保等待超时时间大于录制时间*/ u32 wait_bits = CHAN_REQ_DONE(rx_chan_id) | CHAN_REQ_DONE(tx_chan_id); - - ev = xEventGroupWaitBits(chan_evt, wait_bits, pdTRUE, pdFALSE, portMAX_DELAY); + ev = xEventGroupWaitBits(chan_evt, wait_bits, pdTRUE, pdFALSE, wait_timeout); if ((ev & wait_bits) != 0U) { - FI2S_INFO("DDMA transfer success."); - trans_num ++ ; - if (trans_num >= TX_RX_BUF_LEN / per_buffer) /*已经传输完成的数目,传输完一个bdl产生一次中断*/ - { - return ok ; - } + ret = FT_SUCCESS; + FI2S_INFO("transfer success *********\r\n"); } else { @@ -222,220 +172,252 @@ static boolean FFreeRTOSI2sWaitDmaEnd(void) { FI2S_ERROR("Both TX and RX timeout."); } - ok = FALSE; } - - return FALSE; + return ret; } -static void FFreeRTOSI2sHardWareConfig(u32 work_mode) +/*I2s playback function*/ +static FError I2sPlayback(void) { - FError err = FT_SUCCESS; - - /*设置es8336芯片*/ - FEs8336RegsProbe(); /* 寄存器默认值 */ + FError ret = FT_SUCCESS; FEs8336Startup(); - err = FEs8336SetFormat(i2s_config.word_length); /* 设置ES8336工作模式 */ - FASSERT_MSG(FT_SUCCESS == err, "set es8336 failed."); + ret = FFreeRTOSDdmaBDLStartChannel(ddma, tx_chan_id); + if (ret != FT_SUCCESS) + { + FI2S_ERROR("Ddma set config failed."); + goto exit; + } +exit: + return ret; +} - /*设置i2s模块*/ - err = FI2sClkOutDiv(&os_i2s->i2s_ctrl); /* 默认16-bits采集 */ - FASSERT_MSG(FT_SUCCESS == err, "set i2s clk failed."); - FI2sSetHwconfig(&os_i2s->i2s_ctrl); - FI2sTxRxEnable(&os_i2s->i2s_ctrl, TRUE); /* 模块使能 */ +/*I2s receive function*/ +static FError I2sReceive(void) +{ + FError ret = FT_SUCCESS; + FEs8336Startup(); + FFreeRTOSDdmaBDLStartChannel(ddma, rx_chan_id); + if (ret != FT_SUCCESS) + { + FI2S_ERROR("Ddma set config failed."); + goto exit; + } +exit: + return ret; +} +static FError DdmaInit(void) +{ + FError ret = FT_SUCCESS; + /*初始化ddma*/ + ddma = FFreeRTOSDdmaInit(FDDMA2_I2S_ID, &ddma_config); /* init DDMA */ + if (ddma == NULL) + { + FI2S_ERROR("Init i2s failed."); + return FI2S_ERR_CONFIG_SET_FAILED; + goto exit; + } /*ddma bdl配置*/ + fsize_t bdl_num = TX_RX_BUF_LEN / per_buffer; - err = FMempInit(&memp, memp_buf, memp_buf + sizeof(memp_buf)); - FCacheDCacheFlushRange((uintptr)rx_buf, TX_RX_BUF_LEN); + ret = FMempInit(&memp, memp_buf, memp_buf + sizeof(memp_buf)); + FCacheDCacheFlushRange((uintptr)data_buf, TX_RX_BUF_LEN); for (u32 chan = FDDMA_CHAN_0; chan < FDDMA_NUM_OF_CHAN; chan++) /* 清除中断 */ { FDdmaClearChanIrq(ddma->ctrl.config.base_addr, chan, ddma->ctrl.config.caps); u32 status = FDdmaReadReg(ddma->ctrl.config.base_addr, FDDMA_STA_OFFSET); + } /* set BDL descriptors */ for (fsize_t loop = 0; loop < bdl_num; loop++) { bdl_desc_config[loop].current_desc_num = loop; - bdl_desc_config[loop].src_addr = (uintptr)(rx_buf + per_buffer * loop); + bdl_desc_config[loop].src_addr = (uintptr)(data_buf + per_buffer * loop); bdl_desc_config[loop].trans_length = per_buffer; - bdl_desc_config[loop].ioc = TRUE; + bdl_desc_config[loop].ioc = FALSE; } - FDdmaBdlDesc *bdl_desc_list = FMempMallocAlign(&memp, bdl_num * sizeof(FDdmaBdlDesc), FDDMA_BDL_ADDR_ALIGMENT); - memset(bdl_desc_list, 0, bdl_num * sizeof(FDdmaBdlDesc)); - bdl_desc_list_g = bdl_desc_list; + bdl_desc_config[bdl_num - 1].ioc = TRUE; + bdl_desc_list_g = FMempMallocAlign(&memp, bdl_num * sizeof(FDdmaBdlDesc), FDDMA_BDL_ADDR_ALIGMENT); + memset(bdl_desc_list_g, 0, bdl_num * sizeof(FDdmaBdlDesc)); /* set BDL descriptor list with descriptor configs */ for (fsize_t loop = 0; loop < bdl_num; loop++) { - FDdmaBDLSetDesc(bdl_desc_list, &bdl_desc_config[loop]); + FDdmaBDLSetDesc(bdl_desc_list_g, &bdl_desc_config[loop]); } - if (work_mode == AUDIO_PCM_STREAM_CAPTURE) + rx_request.slave_id = 0U; + rx_request.mem_addr = (uintptr)data_buf; + rx_request.dev_addr = os_i2s->i2s_ctrl.config.base_addr + FI2S_RXDMA; + rx_request.trans_len = TX_RX_BUF_LEN; + rx_request.is_rx = TRUE; + rx_request.req_done_handler = DdmaI2sAckDMADone; + rx_request.req_done_args = NULL; + rx_request.first_desc_addr = (uintptr)bdl_desc_list_g; + rx_request.valid_desc_num = bdl_num; + ret = FFreeRTOSDdmaSetupBDLChannel(ddma, rx_chan_id, &rx_request); + + if (ret != FT_SUCCESS) { - rx_tx_request.slave_id = 0U; - rx_tx_request.mem_addr = (uintptr)rx_buf; - rx_tx_request.dev_addr = os_i2s->i2s_ctrl.config.base_addr + FI2S_RXDMA; - rx_tx_request.trans_len = TX_RX_BUF_LEN; - rx_tx_request.is_rx = TRUE; - rx_tx_request.req_done_handler = DdmaI2sAckDMADone; - rx_tx_request.req_done_args = NULL; - rx_tx_request.first_desc_addr = (uintptr)bdl_desc_list; - rx_tx_request.valid_desc_num = bdl_num; - err = FFreeRTOSDdmaSetupBDLChannel(ddma, rx_chan_id, &rx_tx_request); - FFreeRTOSDdmaBDLStartChannel(ddma, rx_chan_id); + FI2S_ERROR("Ddma set config failed."); + goto exit; } - else + tx_request.slave_id = 0U; + tx_request.mem_addr = (uintptr)data_buf; + tx_request.dev_addr = os_i2s->i2s_ctrl.config.base_addr + FI2S_TXDMA; + tx_request.trans_len = TX_RX_BUF_LEN; + tx_request.is_rx = FALSE; + tx_request.req_done_handler = DdmaI2sAckDMADone; + tx_request.req_done_args = NULL; + tx_request.first_desc_addr = (uintptr)bdl_desc_list_g; + tx_request.valid_desc_num = bdl_num; + ret = FFreeRTOSDdmaSetupBDLChannel(ddma, tx_chan_id, &tx_request); + + if (ret != FT_SUCCESS) { - rx_tx_request.slave_id = 0U; - rx_tx_request.mem_addr = (uintptr)(void *)rx_buf; - rx_tx_request.dev_addr = os_i2s->i2s_ctrl.config.base_addr + FI2S_TXDMA; - rx_tx_request.trans_len = TX_RX_BUF_LEN; - rx_tx_request.is_rx = FALSE; - rx_tx_request.req_done_handler = DdmaI2sAckDMADone; - rx_tx_request.req_done_args = NULL; - rx_tx_request.first_desc_addr = (uintptr)bdl_desc_list; - rx_tx_request.valid_desc_num = bdl_num; - err = FFreeRTOSDdmaSetupBDLChannel(ddma, tx_chan_id, &rx_tx_request); - FFreeRTOSDdmaBDLStartChannel(ddma, tx_chan_id); + FI2S_ERROR("Ddma set config failed."); + goto exit; } +exit: + return ret; } -static void FFreeRTOSI2sInitTask(void *pvParameters) +/*I2s trans init function*/ +static FError I2sInit(void) { - FError err = FT_SUCCESS; - const u32 i2s_id = FI2S0_ID;/* 默认使用I2S-0 */ - const u32 ddma_id = FDDMA2_I2S_ID; /* I2S所绑定的DDMA默认是DDMA-2 */ - + FError ret = FT_SUCCESS; /*先初始化es8336*/ FIOMuxInit(); FIOPadSetI2sMux(); - err = FEs8336Init(); /* es8336初始化,I2C slave设置 */ - FASSERT_MSG(FT_SUCCESS == err, "Init es8336 failed."); - - /*初始化i2s*/ - os_i2s = FFreeRTOSI2sInit(i2s_id); - FASSERT_MSG(os_i2s, "Init i2s failed."); - - /*初始化ddma*/ - ddma = FFreeRTOSDdmaInit(ddma_id, &ddma_config); /* init DDMA */ - FASSERT_MSG(ddma, "Init DDMA failed."); - vTaskDelete(NULL); -} - -static void FFreeRTOSI2sReceiveTask(void *pvParameters) -{ - FError err = FT_SUCCESS; - u32 work_mode = AUDIO_PCM_STREAM_CAPTURE; + ret = FEs8336Init(); /* es8336初始化,I2C slave设置 */ + if (ret != FT_SUCCESS) + { + FI2S_ERROR("Init es8336 failed."); + goto exit; + } + FEs8336RegsProbe(); /* 寄存器默认值 */ - FFreeRTOSI2sHardWareConfig(work_mode); + ret = FEs8336SetFormat(FI2S_WORLD_LENGTH_16); /* 设置ES8336工作模式 */ + if (ret != FT_SUCCESS) + { + FI2S_ERROR("Init es8336 failed."); + goto exit; + } - for (;;) + os_i2s = FFreeRTOSI2sInit(FI2S0_ID); + if (os_i2s == NULL) { - printf("...Waiting for recv data...\r\n"); - /* block recv task until RX done */ - if (!FFreeRTOSI2sWaitDmaEnd()) - { - continue; - } - if ((FFREERTOS_DDMA_OK != FFreeRTOSDdmaStopChannel(ddma, tx_chan_id)) || - (FFREERTOS_DDMA_OK != FFreeRTOSDdmaStopChannel(ddma, rx_chan_id))) - { - FI2S_ERROR("Stop DDMA transfer failed."); - continue; - } - trans_num = 0; - FFreeRTOSI2sDdmaGiveSync(); /* recv finish, give send sync and allow sending */ - FFreeRTOSDdmaStop(ddma); - vTaskDelete(NULL); + FI2S_ERROR("Init i2s failed."); + return FI2S_ERR_CONFIG_SET_FAILED; + goto exit; } + os_i2s->i2s_ctrl.data_config.sample_rate = FI2S_SAMPLE_RATE_CD; + os_i2s->i2s_ctrl.data_config.word_length = FI2S_WORLD_LENGTH_16; + /*设置i2s模块*/ + FFreeRTOSSetupI2S(os_i2s); +exit: + return ret; } -static void FFreeRTOSI2sSendTask(void *pvParameters) +static void FFreeRTOSI2sTransTask(void) { - FFreeRTOSI2sDdmTakeSync();/*receiver task is over , send task take sync from recv and start work*/ - FError err = FT_SUCCESS; - u32 work_mode = AUDIO_PCM_STREAM_PLAYBACK; + int task_res = I2S_TRANS_TEST_SUCCESS; + FError ret = FT_SUCCESS; - FFreeRTOSI2sHardWareConfig(work_mode); + ret = I2sInit(); + if (ret != FT_SUCCESS) + { + FI2S_ERROR("I2sInitFunction failed."); + task_res = I2S_INIT_ERROR; + goto task_exit; + } + ret = DdmaInit(); + if (ret != FT_SUCCESS) + { + FI2S_ERROR("I2sInitFunction failed."); + task_res = I2S_INIT_ERROR; + goto task_exit; + } + ret = I2sReceive(); + if (ret != FT_SUCCESS) + { + FI2S_ERROR("I2sReceive failed."); + task_res = I2S_RECEIVE_ERROR; + goto task_exit; + } + I2sWaitTransferDone();/*等待接收完成,之后开始发送*/ + if (ret != FT_SUCCESS) + { + FI2S_ERROR("I2sWaitRxDone failed."); + goto task_exit; + } - for (;;) + ret = I2sPlayback();/*开始发送*/ + if (ret != FT_SUCCESS) { - printf("...Waiting for send data...\r\n"); - /* block send task until send done */ - if (!FFreeRTOSI2sWaitDmaEnd()) - { - continue; - } - if ((FFREERTOS_DDMA_OK != FFreeRTOSDdmaStopChannel(ddma, tx_chan_id)) || - (FFREERTOS_DDMA_OK != FFreeRTOSDdmaStopChannel(ddma, rx_chan_id))) - { - FI2S_ERROR("Stop DDMA transfer failed."); - continue; - } - trans_num = 0; - FFreeRTOSDdmaStop(ddma); - vTaskDelete(NULL); + FI2S_ERROR("I2sPlayback failed."); + task_res = I2S_PLAYBACK_ERROR; + goto task_exit; } + I2sWaitTransferDone();/*等待发送完成*/ + +task_exit: + xQueueSend(xQueue, &task_res, 0); + vTaskDelete(NULL); } -BaseType_t FFreeRTOSI2sInitCreate(void) +BaseType_t FFreeRTOSRunI2sExample(void) { - BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - + BaseType_t xReturn = pdPASS; /* pdPASS */ + int task_res = I2S_TRANS_TEST_UNKNOWN; FASSERT_MSG(NULL == chan_evt, "Event group exists."); FASSERT_MSG((chan_evt = xEventGroupCreate()) != NULL, "Create event group failed."); - FASSERT_MSG(NULL == sync, "Sync exists."); - FASSERT_MSG((sync = xQueueCreate(1, sizeof(boolean))) != NULL, "Create sync failed."); - - taskENTER_CRITICAL(); /* no schedule when create task */ - - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSI2sInitTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSI2sInitTask",/* 任务名字 */ - (uint16_t)4096, /* 任务栈大小 */ - (void *)NULL,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 2, /* 任务的优先级 */ - (TaskHandle_t *)&i2s_init_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "I2sInitTask creation is failed."); - - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSI2sSendTask, /* task entry */ - (const char *)"FFreeRTOSI2sSendTask",/* task name */ - (uint16_t)4096, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t)configMAX_PRIORITIES - 4, /* task priority */ - (TaskHandle_t *)&i2s_Trans_handle); /* task handler */ - - FASSERT_MSG(pdPASS == xReturn, "Create task failed."); + xQueue = xQueueCreate(1, sizeof(int)); /* create queue for task communication */ + if (is_running) + { + FI2S_ERROR("The task is running."); + return pdPASS; + } - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSI2sReceiveTask, /* task entry */ - (const char *)"FFreeRTOSI2sReceiveTask",/* task name */ - (uint16_t)4096, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t)configMAX_PRIORITIES - 3, /* task priority */ - (TaskHandle_t *)&i2s_receive_handle); /* task handler */ + is_running = TRUE; - FASSERT_MSG(pdPASS == xReturn, "Create task failed."); - taskEXIT_CRITICAL(); /* allow schedule since task created */ + if (xQueue == NULL) + { + FI2S_ERROR("xQueue create failed."); + goto exit; + } + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSI2sTransTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSI2sTransTask", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)I2S_TEST_TASK_PRIORITY, /* 任务优先级 */ + NULL); /* 任务句柄 */ + if (xReturn == pdFAIL) + { + FI2S_ERROR("xTaskCreate I2s trans task failed."); + goto exit; + } + xReturn = xQueueReceive(xQueue, &task_res, portMAX_DELAY); + if (xReturn == pdFAIL) + { + FI2S_ERROR("xQueue receive timeout."); + goto exit; + } - return xReturn; +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } + FFreeRTOSI2sDeinit(); + if (task_res != I2S_TRANS_TEST_SUCCESS) + { + printf("%s@%d: I2s trans example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return pdFAIL; + } + else + { + printf("%s@%d: I2s trans example [success].\r\n", __func__, __LINE__); + return pdTRUE; + } } - -BaseType_t FFreeRTOSI2sDeInitCreate(void) -{ - BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - - taskENTER_CRITICAL(); /* no schedule when create task */ - - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSI2sDeinitTask, /* task entry */ - (const char *)"FFreeRTOSI2sDeinitTask",/* task name */ - (uint16_t)4096, /* task stack size in words */ - NULL, /* task params */ - (UBaseType_t)configMAX_PRIORITIES - 3, /* task priority */ - (TaskHandle_t *)&i2s_deinit_handle); /* task handler */ - - FASSERT_MSG(pdPASS == xReturn, "Create task failed."); - - taskEXIT_CRITICAL(); /* allow schedule since task created */ - - return xReturn; -} \ No newline at end of file diff --git a/example/peripheral/media/lvgl_demo/inc/lv_demo_creat.h b/example/peripheral/media/lvgl_demo/inc/lv_demo_create.h similarity index 91% rename from example/peripheral/media/lvgl_demo/inc/lv_demo_creat.h rename to example/peripheral/media/lvgl_demo/inc/lv_demo_create.h index cca0c18d262ea81d3ef4f14d0f9ecfe0332848cb..cc18bcaa29e36b3ef490543657165b89117222b9 100644 --- a/example/peripheral/media/lvgl_demo/inc/lv_demo_creat.h +++ b/example/peripheral/media/lvgl_demo/inc/lv_demo_create.h @@ -10,7 +10,7 @@ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the Phytium Public License for more details. * - * FilePath: lv_demo_creat.h + * FilePath: lv_demo_create.h * Date: 2023-02-05 18:27:47 * LastEditTime: 2023-07-07 11:02:47 * Description: This file is for providing the lvgl demo config @@ -23,8 +23,8 @@ */ -#ifndef LV_DEMO_CREAT_H -#define LV_DEMO_CREAT_H +#ifndef LV_DEMO_CREATE_H +#define LV_DEMO_CREATE_H #ifdef __cplusplus extern "C" { @@ -49,13 +49,13 @@ typedef struct u32 refresh_rate; } InputParm; -/*creat the media demo init task*/ +/*create the media demo init task*/ BaseType_t FFreeRTOSlVGLDemoCreate(void); -/*creat the media init task*/ +/*create the media init task*/ BaseType_t FFreeRTOSMediaInitCreate(void ); -/*creat the lvgl config task*/ +/*create the lvgl config task*/ BaseType_t FFreeRTOSlVGLConfigCreate(void); #if LV_USE_DEMO_BENCHMARK diff --git a/example/peripheral/media/lvgl_demo/src/cmd.c b/example/peripheral/media/lvgl_demo/src/cmd.c index c5a1af063a21bf83c2eb037803aec475bbede47a..477a51d068dbab60a73f7819298f4c310314a335 100644 --- a/example/peripheral/media/lvgl_demo/src/cmd.c +++ b/example/peripheral/media/lvgl_demo/src/cmd.c @@ -36,7 +36,7 @@ #include "lv_port_disp.h" #include "lv_obj.h" #include "lv_conf.h" -#include "lv_demo_creat.h" +#include "lv_demo_create.h" #include "lv_demo_test.h" static void FFreeRTOSMediaCmdUsage(void) diff --git a/example/peripheral/media/lvgl_demo/src/lv_demo_creat.c b/example/peripheral/media/lvgl_demo/src/lv_demo_create.c similarity index 96% rename from example/peripheral/media/lvgl_demo/src/lv_demo_creat.c rename to example/peripheral/media/lvgl_demo/src/lv_demo_create.c index 34ba434b0e54b7770c25b8c28bd347b34e8c3ae1..dbfc53564d43c029a0c2b9f293dd3e8d74bd5319 100644 --- a/example/peripheral/media/lvgl_demo/src/lv_demo_creat.c +++ b/example/peripheral/media/lvgl_demo/src/lv_demo_create.c @@ -32,7 +32,7 @@ #include "fassert.h" #include "fkernel.h" -#include "lv_demo_creat.h" +#include "lv_demo_create.h" #include "lv_demo_test.h" #include "lv_port_disp.h" @@ -170,8 +170,8 @@ static void FFreeRTOSLVGLDemoTask(void) /** * @name: FFreeRTOSMediaInitCreate - * @msg: creat the media init task - * @return xReturn,pdPASS:success,others:creat failed + * @msg: create the media init task + * @return xReturn,pdPASS:success,others:create failed */ BaseType_t FFreeRTOSMediaInitCreate(void) { @@ -201,7 +201,7 @@ BaseType_t FFreeRTOSMediaInitCreate(void) /** * @name: FFreeRTOSlVGLConfigCreate * @msg: set the lvgl init task - * @return xReturn,pdPASS:success,others:creat failed + * @return xReturn,pdPASS:success,others:create failed */ BaseType_t FFreeRTOSlVGLConfigCreate(void ) { @@ -224,8 +224,8 @@ BaseType_t FFreeRTOSlVGLConfigCreate(void ) /** * @name: FFreeRTOSlVGLDemoCreate - * @msg: creat the media demo init task - * @return xReturn,pdPASS:success,others:creat failed + * @msg: create the media demo init task + * @return xReturn,pdPASS:success,others:create failed */ BaseType_t FFreeRTOSlVGLDemoCreate(void) { diff --git a/example/peripheral/media/lvgl_indev/inc/lv_indev_creat.h b/example/peripheral/media/lvgl_indev/inc/lv_indev_create.h similarity index 93% rename from example/peripheral/media/lvgl_indev/inc/lv_indev_creat.h rename to example/peripheral/media/lvgl_indev/inc/lv_indev_create.h index ab2249f6bd0b261a1d4463e44430306bc975eda7..4157b3092bff5e6dade995def40c922c2bb7d789 100644 --- a/example/peripheral/media/lvgl_indev/inc/lv_indev_creat.h +++ b/example/peripheral/media/lvgl_indev/inc/lv_indev_create.h @@ -10,7 +10,7 @@ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the Phytium Public License for more details. * - * FilePath: lv_indev_creat.h + * FilePath: lv_indev_create.h * Date: 2023-02-05 18:27:47 * LastEditTime: 2023-07-07 11:02:47 * Description: This file is for providing the lvgl task @@ -23,8 +23,8 @@ */ -#ifndef LV_INDEV_CREAT_H -#define LV_INDEV_CREAT_H +#ifndef LV_INDEV_CREATE_H +#define LV_INDEV_CREATE_H #ifdef __cplusplus extern "C" { @@ -40,7 +40,7 @@ extern "C" { #include "lvgl-8.3/lvgl.h" #endif -/*creat the media demo init task*/ +/*create the media demo init task*/ BaseType_t FFreeRTOSDemoCreate(void); /*init the keyboard*/ diff --git a/example/peripheral/media/lvgl_indev/src/cmd.c b/example/peripheral/media/lvgl_indev/src/cmd.c index 2e4690cf38e8f081dc5fa81ab0b5274faad3f49c..804a4bb48e88a54b94d135947d84477b3b589886 100644 --- a/example/peripheral/media/lvgl_indev/src/cmd.c +++ b/example/peripheral/media/lvgl_indev/src/cmd.c @@ -36,7 +36,7 @@ #include "lv_port_disp.h" #include "lv_obj.h" #include "lv_conf.h" -#include "lv_indev_creat.h" +#include "lv_indev_create.h" #include "lv_indev_test.h" static void FFreeRTOSMediaCmdUsage(void) diff --git a/example/peripheral/media/lvgl_indev/src/lv_indev_creat.c b/example/peripheral/media/lvgl_indev/src/lv_indev_create.c similarity index 96% rename from example/peripheral/media/lvgl_indev/src/lv_indev_creat.c rename to example/peripheral/media/lvgl_indev/src/lv_indev_create.c index 40be722f14ca2a8abf5679002b5f2b76f0e6c202..8f14117224f46a6f73449a312be44b3ba9ba8bbd 100644 --- a/example/peripheral/media/lvgl_indev/src/lv_indev_creat.c +++ b/example/peripheral/media/lvgl_indev/src/lv_indev_create.c @@ -10,10 +10,10 @@ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the Phytium Public License for more details. * - * FilePath: lv_indev_creat.c + * FilePath: lv_indev_create.c * Date: 2023-02-05 18:27:47 * LastEditTime: 2023-07-07 11:02:47 - * Description: This file is for providing the lvgl task creat + * Description: This file is for providing the lvgl task create * * Modify History: * Ver   Who        Date         Changes @@ -31,7 +31,7 @@ #include "fassert.h" #include "../lvgl.h" -#include "lv_indev_creat.h" +#include "lv_indev_create.h" #include "lv_indev_port.h" #include "lv_indev_test.h" #include "lv_port_disp.h" @@ -137,7 +137,7 @@ BaseType_t FFreeRTOSInitMsCreate(u32 id) /** * @name: FFreeRTOSMediaInitCreate * @msg: set the media init task - * @return xReturn,pdPASS:success,others:creat failed + * @return xReturn,pdPASS:success,others:create failed */ BaseType_t FFreeRTOSMediaInitCreate(void ) { @@ -166,7 +166,7 @@ BaseType_t FFreeRTOSMediaInitCreate(void ) /** * @name: FFreeRTOSlVGLConfigCreate * @msg: set the lvgl init task - * @return xReturn,pdPASS:success,others:creat failed + * @return xReturn,pdPASS:success,others:create failed */ BaseType_t FFreeRTOSlVGLConfigCreate(void) { @@ -189,8 +189,8 @@ BaseType_t FFreeRTOSlVGLConfigCreate(void) /** * @name: FFreeRTOSDemoCreate - * @msg: creat the lvgl demo task - * @return xReturn,pdPASS:success,others:creat failed + * @msg: create the lvgl demo task + * @return xReturn,pdPASS:success,others:create failed */ BaseType_t FFreeRTOSDemoCreate(void) { diff --git a/example/peripheral/media/lvgl_ui/inc/lv_indev_creat.h b/example/peripheral/media/lvgl_ui/inc/lv_indev_create.h similarity index 93% rename from example/peripheral/media/lvgl_ui/inc/lv_indev_creat.h rename to example/peripheral/media/lvgl_ui/inc/lv_indev_create.h index cad0abdf3a01247f529895e2b167bde3d94f6355..09f9c4eb16cb46aea435bc83a061dfc9129d4a2f 100644 --- a/example/peripheral/media/lvgl_ui/inc/lv_indev_creat.h +++ b/example/peripheral/media/lvgl_ui/inc/lv_indev_create.h @@ -10,7 +10,7 @@ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the Phytium Public License for more details. * - * FilePath: lv_indev_creat.h + * FilePath: lv_indev_create.h * Date: 2023-02-05 18:27:47 * LastEditTime: 2023-07-07 11:02:47 * Description: This file is for providing the lvgl indev task @@ -23,8 +23,8 @@ */ -#ifndef LV_INDEV_CREAT_H -#define LV_INDEV_CREAT_H +#ifndef LV_INDEV_CREATE_H +#define LV_INDEV_CREATE_H #ifdef __cplusplus extern "C" { @@ -40,7 +40,7 @@ extern "C" { #include "lvgl-8.3/lvgl.h" #endif -/*creat the media demo init task*/ +/*create the media demo init task*/ BaseType_t FFreeRTOSDemoCreate(void); /*init the keyboard*/ diff --git a/example/peripheral/media/lvgl_ui/src/cmd.c b/example/peripheral/media/lvgl_ui/src/cmd.c index 2e4690cf38e8f081dc5fa81ab0b5274faad3f49c..804a4bb48e88a54b94d135947d84477b3b589886 100644 --- a/example/peripheral/media/lvgl_ui/src/cmd.c +++ b/example/peripheral/media/lvgl_ui/src/cmd.c @@ -36,7 +36,7 @@ #include "lv_port_disp.h" #include "lv_obj.h" #include "lv_conf.h" -#include "lv_indev_creat.h" +#include "lv_indev_create.h" #include "lv_indev_test.h" static void FFreeRTOSMediaCmdUsage(void) diff --git a/example/peripheral/media/lvgl_ui/src/lv_indev_creat.c b/example/peripheral/media/lvgl_ui/src/lv_indev_create.c similarity index 96% rename from example/peripheral/media/lvgl_ui/src/lv_indev_creat.c rename to example/peripheral/media/lvgl_ui/src/lv_indev_create.c index 66ce2ac5708dfcf067dc36f6b03e4a424c098958..37ff45d4984b63a2e3f1f76c568b7d04556e8ced 100644 --- a/example/peripheral/media/lvgl_ui/src/lv_indev_creat.c +++ b/example/peripheral/media/lvgl_ui/src/lv_indev_create.c @@ -10,10 +10,10 @@ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the Phytium Public License for more details. * - * FilePath: lv_indev_creat.c + * FilePath: lv_indev_create.c * Date: 2023-02-05 18:27:47 * LastEditTime: 2023-07-07 11:02:47 - * Description: This file is for providing the lvgl task creat + * Description: This file is for providing the lvgl task create * * Modify History: * Ver   Who        Date         Changes @@ -31,7 +31,7 @@ #include "fassert.h" #include "../lvgl.h" -#include "lv_indev_creat.h" +#include "lv_indev_create.h" #include "lv_indev_port.h" #include "lv_indev_test.h" #include "lv_port_disp.h" @@ -137,7 +137,7 @@ BaseType_t FFreeRTOSInitMsCreate(u32 id) /** * @name: FFreeRTOSMediaInitCreate * @msg: set the media init task - * @return xReturn,pdPASS:success,others:creat failed + * @return xReturn,pdPASS:success,others:create failed */ BaseType_t FFreeRTOSMediaInitCreate(void ) { @@ -166,7 +166,7 @@ BaseType_t FFreeRTOSMediaInitCreate(void ) /** * @name: FFreeRTOSlVGLConfigCreate * @msg: set the lvgl init task - * @return xReturn,pdPASS:success,others:creat failed + * @return xReturn,pdPASS:success,others:create failed */ BaseType_t FFreeRTOSlVGLConfigCreate(void) { @@ -189,8 +189,8 @@ BaseType_t FFreeRTOSlVGLConfigCreate(void) /** * @name: FFreeRTOSDemoCreate - * @msg: creat the lvgl demo task - * @return xReturn,pdPASS:success,others:creat failed + * @msg: create the lvgl demo task + * @return xReturn,pdPASS:success,others:create failed */ BaseType_t FFreeRTOSDemoCreate(void) { diff --git a/example/peripheral/pwm/src/pwm_dead_band_example.c b/example/peripheral/pwm/src/pwm_dead_band_example.c index aa752106481133a4e6fcff7b4774e57508b50c25..74f2fb490d883966205486769402fda36fc272e2 100644 --- a/example/peripheral/pwm/src/pwm_dead_band_example.c +++ b/example/peripheral/pwm/src/pwm_dead_band_example.c @@ -40,6 +40,7 @@ /* pwm pulse change period */ #define PWM_CHANGE_PERIOD (pdMS_TO_TICKS(500UL)) #define TIMER_OUT (pdMS_TO_TICKS(4000UL)) +#define PWM_DEAD_BAND_TEST_TASK_PRIORITY 3 /* pwm pulse amplitude of periodic variation */ #define PWM_PULSE_CHANGE 1000 @@ -212,7 +213,7 @@ BaseType_t FFreeRTOSPwmDeadBandTaskCreate() (const char *)"FFreeRTOSPwmDeadBandTask", /* 任务名字 */ (uint16_t)4096, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ - (UBaseType_t)2, /* 任务优先级 */ + (UBaseType_t)PWM_DEAD_BAND_TEST_TASK_PRIORITY, /* 任务优先级 */ NULL); /* 任务句柄 */ if (xReturn == pdFAIL) { diff --git a/example/peripheral/pwm/src/pwm_dual_channel_example.c b/example/peripheral/pwm/src/pwm_dual_channel_example.c index 8c564c72f4940749e9c4fd7b93da2291822c0f0b..3f37c9fb77c6ecc25611f33a00e2aba1ecb5182c 100644 --- a/example/peripheral/pwm/src/pwm_dual_channel_example.c +++ b/example/peripheral/pwm/src/pwm_dual_channel_example.c @@ -40,6 +40,7 @@ /* pwm pulse change period */ #define PWM_CHANGE_PERIOD (pdMS_TO_TICKS(500UL)) #define TIMER_OUT (pdMS_TO_TICKS(10000UL)) +#define PWM_DUAL_CHANNEL_TEST_TASK_PRIORITY 3 /* pwm pulse amplitude of periodic variation */ #define PWM_PULSE_CHANGE 1000 @@ -206,7 +207,7 @@ BaseType_t FFreeRTOSPwmDualChannelTaskCreate() (const char *)"FFreeRTOSPwmDualChannelTask", /* 任务名字 */ (uint16_t)4096, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ - (UBaseType_t)2, /* 任务优先级 */ + (UBaseType_t)PWM_DUAL_CHANNEL_TEST_TASK_PRIORITY, /* 任务优先级 */ NULL); /* 任务句柄 */ if (xReturn == pdFAIL) { diff --git a/example/peripheral/pwm/src/pwm_single_channel_example.c b/example/peripheral/pwm/src/pwm_single_channel_example.c index 14cd80a1d1c379818da525ed22d04baeecd5ca3b..0faa5438c9b7c0420bc8a1ce2c1fbbbd8e5ce477 100644 --- a/example/peripheral/pwm/src/pwm_single_channel_example.c +++ b/example/peripheral/pwm/src/pwm_single_channel_example.c @@ -40,6 +40,7 @@ /* pwm pulse change period */ #define PWM_CHANGE_PERIOD (pdMS_TO_TICKS(500UL)) #define TIMER_OUT (pdMS_TO_TICKS(10000UL)) +#define PWM_SINGLE_CHANNEL_TEST_TASK_PRIORITY 3 /* pwm pulse amplitude of periodic variation */ #define PWM_PULSE_CHANGE 1000 @@ -176,7 +177,7 @@ BaseType_t FFreeRTOSPwmSingleChannelTaskCreate() (const char *)"FFreeRTOSSingleChannelTask", /* 任务名字 */ (uint16_t)4096, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ - (UBaseType_t)2, /* 任务优先级 */ + (UBaseType_t)PWM_SINGLE_CHANNEL_TEST_TASK_PRIORITY, /* 任务优先级 */ NULL); /* 任务句柄 */ if (xReturn == pdFAIL) { diff --git a/example/peripheral/qspi/README.md b/example/peripheral/qspi/README.md index bc06d1e7581e49e304fb9b9233a0b1d6e7bf74bf..7ace822790aba620bec1806119815922fc43028c 100644 --- a/example/peripheral/qspi/README.md +++ b/example/peripheral/qspi/README.md @@ -45,7 +45,7 @@ E2000D上使用的Nor Flash介质型号是GD25Q128,容量为16MB; 本例程需要用到 - Phytium开发板:FT2000-4/D2000/E2000D/E2000Q/PhytiumPi(包含QSPI-FLASH芯片座) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 diff --git a/example/peripheral/qspi/main.c b/example/peripheral/qspi/main.c index 4b90ee5f1a4d739c724bcd20c12462fc94905b1b..ce906a1efa30980a46bcd098fac97c0a91e80983 100644 --- a/example/peripheral/qspi/main.c +++ b/example/peripheral/qspi/main.c @@ -20,6 +20,7 @@ * Ver   Who         Date          Changes * ----- ------      --------     -------------------------------------- * 1.0 wangxiaodong 2022/8/9 first release + * 1.1 zhangyan 2024/4/29 add no letter shell mode, adapt to auto-test system */ #include @@ -31,6 +32,7 @@ #else #include "task.h" #include "qspi_example.h" +#define QSPI_EXAMPLE_TASK_PRIORITY 2 void QspiExampleTaskEntry() { FFreeRTOSQspiCheckTaskCreate(); @@ -59,7 +61,7 @@ int main(void) (const char *)"QspiExampleTaskEntry", /* 任务名字 */ (uint16_t)4096, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ - (UBaseType_t)5, /* 任务的优先级 */ + (UBaseType_t)QSPI_EXAMPLE_TASK_PRIORITY, /* 任务的优先级 */ NULL); taskEXIT_CRITICAL(); /*退出临界区*/ #endif diff --git a/example/peripheral/qspi/src/qspi_dual_flash_stack_example.c b/example/peripheral/qspi/src/qspi_dual_flash_stack_example.c index 5ee76c9678da5b114efeef965d89c81df9e210b7..a5953a19d4b5717d668a242dc6cb5e88c50ce93c 100644 --- a/example/peripheral/qspi/src/qspi_dual_flash_stack_example.c +++ b/example/peripheral/qspi/src/qspi_dual_flash_stack_example.c @@ -41,6 +41,7 @@ /* write and read task delay in milliseconds */ #define TASK_DELAY_MS 1000UL #define TIMER_OUT (pdMS_TO_TICKS(5000UL)) +#define QSPI_DUAL_FLASH_TEST_TASK_PRIORITY 3 /* Offset 1M from flash maximum capacity*/ #define FLASH_WR_OFFSET SZ_1M /* write and read start address */ @@ -226,7 +227,7 @@ BaseType_t FFreeRTOSQspiDualFlashTaskCreate(void) (const char *)"FFreeRTOSQspiDualFlashTask", /* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (UBaseType_t)QSPI_DUAL_FLASH_TEST_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ taskEXIT_CRITICAL(); /*退出临界区*/ diff --git a/example/peripheral/qspi/src/qspi_flash_connection_check_example.c b/example/peripheral/qspi/src/qspi_flash_connection_check_example.c index 505c816db545987717b2db59d17b1a02ed2675e5..ea1d9213e32513fc0955cb0f597a730580efea7a 100644 --- a/example/peripheral/qspi/src/qspi_flash_connection_check_example.c +++ b/example/peripheral/qspi/src/qspi_flash_connection_check_example.c @@ -38,6 +38,7 @@ #define FQSPI_INFO(format, ...) FT_DEBUG_PRINT_I(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) #define FQSPI_DEBUG(format, ...) FT_DEBUG_PRINT_D(FQSPI_DEBUG_TAG, format, ##__VA_ARGS__) +#define QSPI_FLASH_CONNECT_TEST_TASK_PRIORITY 3 #define TIMER_OUT (pdMS_TO_TICKS(5000UL)) enum { @@ -99,7 +100,7 @@ BaseType_t FFreeRTOSQspiCheckTaskCreate(void) (const char *)"QspiConnectCheckTask", /* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ NULL, - (UBaseType_t)2, /* 任务的优先级 */ + (UBaseType_t)QSPI_FLASH_CONNECT_TEST_TASK_PRIORITY, /* 任务的优先级 */ NULL); taskEXIT_CRITICAL(); /*退出临界区*/ if (xReturn == pdFAIL) diff --git a/example/peripheral/qspi/src/qspi_flash_indirect_example.c b/example/peripheral/qspi/src/qspi_flash_indirect_example.c index ec5195341944e37b13db8718c0ff388bdec82b79..e51142d3d57e283c4ff006fb6f0f9374135d8a57 100644 --- a/example/peripheral/qspi/src/qspi_flash_indirect_example.c +++ b/example/peripheral/qspi/src/qspi_flash_indirect_example.c @@ -44,6 +44,7 @@ /* write and read cs channel */ #define QSPI_CS_CHANNEL 0 #define TIMER_OUT (pdMS_TO_TICKS(5000UL)) +#define QSPI_FLASH_INDIRECT_TEST_TASK_PRIORITY 3 #define DAT_LENGTH 64 static u8 rd_buf[DAT_LENGTH] = {0}; static u8 wr_buf[DAT_LENGTH] = {0}; @@ -224,7 +225,7 @@ BaseType_t FFreeRTOSQspiIndirectTaskCreate(void) (const char *)"FFreeRTOSQspiIndirectTask", /* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (UBaseType_t)QSPI_FLASH_INDIRECT_TEST_TASK_PRIORITY, /* 任务的优先级 */ NULL); taskEXIT_CRITICAL(); /*退出临界区*/ if (xReturn == pdFAIL) @@ -253,6 +254,4 @@ exit: printf("%s@%d: Qspi flash indirect example [success].\r\n", __func__, __LINE__); return pdTRUE; } - - return xReturn; } diff --git a/example/peripheral/qspi/src/qspi_flash_polled_example.c b/example/peripheral/qspi/src/qspi_flash_polled_example.c index 539800aa3cfd641aa4e4446d84c1dd2dd3227c4d..4750bcb8c891f4c58d036c1f6dc50430accbcf22 100644 --- a/example/peripheral/qspi/src/qspi_flash_polled_example.c +++ b/example/peripheral/qspi/src/qspi_flash_polled_example.c @@ -42,7 +42,7 @@ /* write and read task delay in milliseconds */ #define TASK_DELAY_MS 1000UL #define TIMER_OUT (pdMS_TO_TICKS(5000UL)) - +#define QSPI_POLLED_TEST_TASK_PRIORITY 3 /* Offset 1M from flash maximum capacity*/ #define FLASH_WR_OFFSET SZ_1M /* write and read start address */ @@ -222,7 +222,7 @@ BaseType_t FFreeRTOSQspiPolledTaskCreate(void) (const char *)"FFreeRTOSQspiPolledTask", /* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ NULL, /* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ + (UBaseType_t)QSPI_POLLED_TEST_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ taskEXIT_CRITICAL(); /*退出临界区*/ if (xReturn == pdFAIL) diff --git a/example/peripheral/sdif/README.md b/example/peripheral/sdif/README.md index 77fa5821c049d454117a63b5ea446b504bd8d07a..2d1a7fe529e8426c0f793ba94601900a9149a410 100644 --- a/example/peripheral/sdif/README.md +++ b/example/peripheral/sdif/README.md @@ -26,22 +26,19 @@ SD卡的通信依赖三种数据格式:命令包,响应包,数据包,控 - E2000D - E2000Q -- PHYTIUMPI 对应的配置项是, - CONFIG_TARGET_E2000D - CONFIG_TARGET_E2000Q -- CONFIG_TARGET_PHYTIUMPI -本例程在 E2000-测试板B上完成测试,在测试板B上,SD-0控制器连接TF卡,SD-1控制器连接eMMC +本例程在 E2000 DEMO 板上完成测试,DOMO板上 SD-1控制器连接TF卡,SD-0控制器连接eMMC ### 2.2 SDK配置方法 本例程需要, - 使能Shell -- 使能SPI - 使能SDMMC 对应的配置项是, @@ -53,11 +50,11 @@ SD卡的通信依赖三种数据格式:命令包,响应包,数据包,控 本例子已经提供好具体的编译指令,以下进行介绍: - make load_e2000q_aarch64 将预设64bit e2000q 下的配置加载至工程中 - make load_e2000q_aarch32 将预设32bit e2000q 下的配置加载至工程中 -- make 将目录下的工程进行编译 -- make clean 将目录下的工程进行清理 -- make image 将目录下的工程进行编译,并将生成的elf 复制到目标地址 -- make menuconfig 配置目录下的参数变量 -- make backup_kconfig 将目录下的sdkconfig 备份到./configs下 +- make 将目录下的工程进行编译 +- make clean 将目录下的工程进行清理 +- make image 将目录下的工程进行编译,并将生成的elf 复制到目标地址 +- make menuconfig 配置目录下的参数变量 +- make backup_kconfig 将目录下的sdkconfig 备份到./configs下 具体使用方法为: - 在当前目录下 @@ -108,7 +105,7 @@ bootelf -p 0xa0100000 ### 2.4 输出与实验现象 -- 系统进入后,创建任务初始化tf卡,循环读写Tf卡中第3~6块的内容 +- 系统进入后,创建任务初始化tf卡,读写Tf卡中第0到3块的内容 ``` sd tf @@ -116,8 +113,7 @@ sd tf ![tf](./figs/tf_wr.png) -- 系统进入后,创建任务初始化eMMC,循环读写eMMC中第7~9块的内容 ->注意:飞腾派上没有emmc,无法使用下面的命令 +- 系统进入后,创建任务初始化eMMC,读写eMMC中第0到3块的内容 ``` sd emmc @@ -127,8 +123,7 @@ sd emmc ## 3. 如何解决问题 -Q: 飞腾派上使用例程 -A: 飞腾派上没有emmc,作为外插的sd口连接控制器0,由于 tf 卡中存储了固件和文件系统,此例程的读写可能会损害启动文件,不建议直接使用此例程,关于 tf 卡的使用可以参考 storage 中的 fatfs 例程使用特定分区内的文件系统 +Q: 在飞腾派上使用例程 +A:部分版本的飞腾派上没有emmc,作为外插的sd口连接控制器0,由于 tf 卡中存储了固件和文件系统,此例程的读写可能会损害启动文件,不建议直接使用此例程,关于 tf 卡的使用可以参考 storage 中的 fatfs 例程使用特定分区内的文件系统 - -## 4. 修改历史记录 +## 4. 修改历史记录 \ No newline at end of file diff --git a/example/peripheral/sdif/figs/emmc_wr.png b/example/peripheral/sdif/figs/emmc_wr.png index 4a481dd218477bd73bebe94d15f470f5ddee64a4..f6c7aa098dcc7ea8dcca0369ca67863f1b2688ca 100644 Binary files a/example/peripheral/sdif/figs/emmc_wr.png and b/example/peripheral/sdif/figs/emmc_wr.png differ diff --git a/example/peripheral/sdif/figs/tf_wr.png b/example/peripheral/sdif/figs/tf_wr.png index fb1deccb10de2bb4c2336c0b6df57958923b8fbc..1764081500935e16d129187a1c6b72fcd82c09a7 100644 Binary files a/example/peripheral/sdif/figs/tf_wr.png and b/example/peripheral/sdif/figs/tf_wr.png differ diff --git a/example/peripheral/sdif/inc/sdif_read_write.h b/example/peripheral/sdif/inc/sdif_example.h similarity index 57% rename from example/peripheral/sdif/inc/sdif_read_write.h rename to example/peripheral/sdif/inc/sdif_example.h index 344877cf46b4460fcbe7c7dde767a263ee4cfc34..b5baf59b2cb9c2374d4bd8cd4be60845d4f29142 100644 --- a/example/peripheral/sdif/inc/sdif_read_write.h +++ b/example/peripheral/sdif/inc/sdif_example.h @@ -11,55 +11,38 @@ * See the Phytium Public License for more details. * * - * FilePath: sd_read_write.h + * FilePath: sdif_example.h * Date: 2022-07-18 16:43:35 * LastEditTime: 2022-07-18 16:43:35 * Description:  This file is for providing some sd apis. * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022/8/26 first commit + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first commit + * 2.0 liqiaozhong 2024/4/22 add no letter shell mode, adapt to auto-test system */ -#ifndef SD_READ_WRITE_H -#define SD_READ_WRITE_H + +#ifndef SDIF_EXAMPLE_H +#define SDIF_EXAMPLE_H #ifdef __cplusplus extern "C" { #endif - /***************************** Include Files *********************************/ -#include "sdkconfig.h" -#include "fkernel.h" -/************************** Constant Definitions *****************************/ -#define SD_WORK_IRQ TRUE /* 0 for POLL mode, 1 for IRQ mode */ -#define SD_WORK_DMA TRUE /* 0 for PIO mode, 1 for DMA mode */ -#ifdef CONFIG_TARGET_PHYTIUMPI -#define SD_CONTROLLER_ID FSDIO0_ID -#else -#define SD_CONTROLLER_ID FSDIO1_ID -#endif -#if SD_WORK_DMA -#define SD_MAX_RW_BLK 10U -#else -#define SD_MAX_RW_BLK 4U -#endif +/************************** Constant Definitions *****************************/ -#define SD_BLOCK_SIZE 512UL -#define SD_START_BLOCK 0 -#define SD_USE_BLOCK 3 /************************** Variable Definitions *****************************/ -extern u8 s_dma_buffer[SZ_1M * 4]; -extern u8 rw_buf[SD_MAX_RW_BLK * SD_BLOCK_SIZE]; + /***************** Macros (Inline Functions) Definitions *********************/ /************************** Function Prototypes ******************************/ /*****************************************************************************/ -BaseType_t FFreeRTOSTfWriteRead(void); -BaseType_t FFreeRTOSeMMCWriteRead(void); +int FFreeRTOSTfWriteRead(void); +int FFreeRTOSEmmcWriteRead(void); #ifdef __cplusplus } diff --git a/example/peripheral/sdif/main.c b/example/peripheral/sdif/main.c index f0d71f2f4c607ef773bba8aeedcc42d2cb0211df..07986f0398222eac6350ccc30cfe39a014de930c 100644 --- a/example/peripheral/sdif/main.c +++ b/example/peripheral/sdif/main.c @@ -16,21 +16,54 @@ * LastEditTime: 2022-06-17 08:17:59 * Description: This file is for sdio test main entry. * - * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022/8/26 first commit + * Modify History: + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first commit + * 2.0 liqiaozhong 2024/4/22 add no letter shell mode, adapt to auto-test system */ +#include + +#include "FreeRTOS.h" + +#include "sdkconfig.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include +#else +#include "task.h" +#include "sdif_example.h" -int main(void) +#define GDMA_EXAMPLE_TASK_PRIORITY 2 + +void SdifExampleTaskEntry() { - BaseType_t ret; + /* example functions */ + FFreeRTOSTfWriteRead(); + FFreeRTOSEmmcWriteRead(); + + /* end flag */ + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif - ret = LSUserShellTask() ; +int main(void) +{ + BaseType_t ret = pdPASS; +#ifdef CONFIG_USE_LETTER_SHELL + ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)SdifExampleTaskEntry, /* 任务入口函数 */ + (const char *)"SdifExampleTaskEntry", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)GDMA_EXAMPLE_TASK_PRIORITY, /* 任务优先级 */ + NULL); /* 任务句柄 */ +#endif if (ret != pdPASS) { goto FAIL_EXIT; @@ -40,6 +73,6 @@ int main(void) while (1); FAIL_EXIT: - printf("Failed,the ret value is 0x%x. \r\n", ret); - return 0; -} + printf("SDIF example failed in main.c, the ret value is 0x%x. \r\n", ret); + return -2; +} \ No newline at end of file diff --git a/example/peripheral/sdif/makefile b/example/peripheral/sdif/makefile index 8cdbb131737371bf472dd0695f73ceba32b2c1a4..a6e4a04dac36979fae7433102a9b6357801bc275 100644 --- a/example/peripheral/sdif/makefile +++ b/example/peripheral/sdif/makefile @@ -22,8 +22,8 @@ USR_BOOT_DIR ?= /mnt/d/tftboot image: - $(MAKE) clean - $(MAKE) all -j + @$(MAKE) -s clean + @$(MAKE) -s all -j @cp ./$(IMAGE_OUT_NAME).elf $(USR_BOOT_DIR)/freertos.elf ifdef CONFIG_OUTPUT_BINARY @cp ./$(IMAGE_OUT_NAME).bin $(USR_BOOT_DIR)/freertos.bin diff --git a/example/peripheral/sdif/src/cmd_sd.c b/example/peripheral/sdif/src/cmd_sdif.c similarity index 71% rename from example/peripheral/sdif/src/cmd_sd.c rename to example/peripheral/sdif/src/cmd_sdif.c index 9603d059b7d3ad5f1f042fd8fdfd89f76e07fa01..5ecf5a33b590f79739fd9f9380df5f201f3c43e1 100644 --- a/example/peripheral/sdif/src/cmd_sd.c +++ b/example/peripheral/sdif/src/cmd_sdif.c @@ -11,26 +11,29 @@ * See the Phytium Public License for more details. * * - * FilePath: cmd_sd.c + * FilePath: cmd_sdif.c * Date: 2022-07-12 09:33:12 * LastEditTime: 2022-07-12 09:33:12 * Description:  This file is for providing user command functions. * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022/8/26 first commit + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first commit + * 2.0 liqiaozhong 2024/4/22 add no letter shell mode, adapt to auto-test system */ + /***************************** Include Files *********************************/ -#include #include +#include #include "strto.h" -#include "sdkconfig.h" -#include "FreeRTOS.h" +#include "sdkconfig.h" +#ifdef CONFIG_USE_LETTER_SHELL #include "../src/shell.h" -#include "sdif_read_write.h" +#include "sdif_example.h" +#endif /************************** Constant Definitions *****************************/ /**************************** Type Definitions *******************************/ @@ -42,19 +45,19 @@ /************************** Variable Definitions *****************************/ /*****************************************************************************/ +#ifdef CONFIG_USE_LETTER_SHELL static void SdCmdUsage() { printf("Usage:\r\n"); - printf(" sd tf\r\n"); - printf(" -- Demo read and write by sdmmc\r\n"); - printf(" sd emmc\r\n"); - printf(" -- Demo read and write by sdmmc\r\n"); + printf("sd tf\r\n"); + printf("-- Demo read and write by sdmmc\r\n"); + printf("sd emmc\r\n"); + printf("-- Demo read and write by sdmmc\r\n"); } static int SdCmdEntry(int argc, char *argv[]) { int ret = 0; - BaseType_t task_ret = 0U; if (argc < 2) { @@ -64,18 +67,14 @@ static int SdCmdEntry(int argc, char *argv[]) if (!strcmp(argv[1], "tf")) { - task_ret = FFreeRTOSTfWriteRead(); + ret = FFreeRTOSTfWriteRead(); } else if (!strcmp(argv[1], "emmc")) { - task_ret = FFreeRTOSeMMCWriteRead(); - } - - if (pdPASS != task_ret) - { - return -2; + ret = FFreeRTOSEmmcWriteRead(); } - return 0; + return ret; } -SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), sd, SdCmdEntry, test freertos sd rw); \ No newline at end of file +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), sd, SdCmdEntry, test freertos sd rw); +#endif \ No newline at end of file diff --git a/example/peripheral/sdif/src/sdif_emmc_read_write.c b/example/peripheral/sdif/src/sdif_emmc_read_write.c index 1b45aa2323ff315e4e9dbc4724833326ef8dc362..c02363c5cb9a3c94e28b6f22a0d60277158f9aef 100644 --- a/example/peripheral/sdif/src/sdif_emmc_read_write.c +++ b/example/peripheral/sdif/src/sdif_emmc_read_write.c @@ -11,208 +11,192 @@ * See the Phytium Public License for more details. * * - * FilePath: sd_read_write.c + * FilePath: sdif_emmc_read_write.c * Date: 2022-07-25 15:58:24 * LastEditTime: 2022-07-25 15:58:25 - * Description:   This file is for providing functions used in cmd_sd.c file. + * Description: This file is for providing functions used in cmd_sd.c file. * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022/8/26 first commit + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first commit + * 2.0 liqiaozhong 2024/4/22 add no letter shell mode, adapt to auto-test system */ + /***************************** Include Files *********************************/ #include #include #include "FreeRTOS.h" #include "task.h" -#include "event_groups.h" +#include "queue.h" -#include "fassert.h" #include "fdebug.h" -#include "fsleep.h" #include "fkernel.h" -#include "fcache.h" -#include "fio.h" #include "fsdif_timing.h" #include "fsl_sdmmc.h" -#include "sdif_read_write.h" /************************** Constant Definitions *****************************/ -#define SD_EVT_INIT_DONE (0x1 << 0) -#define SD_EVT_WRITE_DONE (0x1 << 1) -#define SD_EVT_READ_DONE (0x1 << 2) +#define FSD_EXAMPLE_TAG "FSD_EXAMPLE" +#define FSD_ERROR(format, ...) FT_DEBUG_PRINT_E(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) +#define FSD_WARN(format, ...) FT_DEBUG_PRINT_W(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) +#define FSD_INFO(format, ...) FT_DEBUG_PRINT_I(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) +#define FSD_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) +#ifdef CONFIG_TARGET_PHYTIUMPI +#define SD_CONTROLLER_ID FSDIO0_ID +#else +#define SD_CONTROLLER_ID FSDIO1_ID +#endif + +/* user-define */ +#define SD_WORK_IRQ TRUE /* 0 for POLL mode, 1 for IRQ mode */ +#define SD_WORK_DMA TRUE /* 0 for PIO mode, 1 for DMA mode */ +#define SD_BLOCK_SIZE 512U +#define SD_START_BLOCK 0U +#define SD_USE_BLOCK 3U +#define RESULT_DISPLAY_LEN 64U /* 用于展示的结果长度 */ +#define SDIF_EXAMPLE_TASK_PRIORITY 3U +#define TIMER_OUT (pdMS_TO_TICKS(4000U)) + +#if SD_WORK_DMA +#define SD_MAX_RW_BLK 10U +#else +#define SD_MAX_RW_BLK 4U +#endif +/**************************** Type Definitions *******************************/ enum { - FSD_EXAMPLE_OK = 0, - FSD_EXAMPLE_NOT_YET_INIT, - FSD_EXAMPLE_INIT_FAILED, - FSD_EXAMPLE_INVALID_PARAM, - FSD_EXAMPLE_READ_WRITE_FAILED, + SDIF_EXAMPLE_SUCCESS = 0, + SDIF_EXAMPLE_UNKNOWN_STATE, + SDIF_EXAMPLE_INIT_FAILURE, + SDIF_EXAMPLE_WRITE_READ_FAILURE, }; -/**************************** Type Definitions *******************************/ - /************************** Variable Definitions *****************************/ static sdmmchost_config_t s_inst_config; -static sdmmc_mmc_t s_inst; +static sdmmc_mmc_t s_inst; + +static QueueHandle_t xQueue = NULL; -static EventGroupHandle_t sync = NULL; -static TaskHandle_t write_task = NULL; -static TimerHandle_t exit_timer = NULL; -static boolean is_running = FALSE; -static u32 run_times = 1U; +static u8 write_buf[SD_MAX_RW_BLK * SD_BLOCK_SIZE] __attribute((aligned(SD_BLOCK_SIZE))) = {0}; +static u8 read_buf[SD_MAX_RW_BLK * SD_BLOCK_SIZE] __attribute((aligned(SD_BLOCK_SIZE))) = {0}; /***************** Macros (Inline Functions) Definitions *********************/ -#define FSD_EXAMPLE_TAG "FSD_EXAMPLE" -#define FSD_ERROR(format, ...) FT_DEBUG_PRINT_E(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) -#define FSD_WARN(format, ...) FT_DEBUG_PRINT_W(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) -#define FSD_INFO(format, ...) FT_DEBUG_PRINT_I(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) -#define FSD_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) + /************************** Function Prototypes ******************************/ /*****************************************************************************/ -static void eMMCExitCallback(TimerHandle_t timer) +static status_t EmmcInit(void) { - FError err = FT_SUCCESS; - printf("Exiting.....\r\n"); + status_t err = kStatus_Success; - if (write_task) + err = MMC_CfgInitialize(&s_inst, &s_inst_config); + if (err != kStatus_Success) { - vTaskDelete(write_task); - write_task = NULL; + FSD_ERROR("Init MMC failed, err = %d !!!", err); + goto task_exit; } - if (sync) +task_exit: + FSD_INFO("%s return with err: %d", __func__, err); + return err; +} + +static status_t EmmcWriteRead(void) +{ + status_t err = kStatus_Success; + + memset(write_buf, 0, sizeof(write_buf)); + memset(read_buf, 0, sizeof(write_buf)); + + for (u32 i = 0; i < SD_USE_BLOCK; i++) /* copy string to write buffer as each block */ { - vEventGroupDelete(sync); - sync = NULL; + memset((write_buf + i * SD_BLOCK_SIZE), (SD_START_BLOCK + i + 1), SD_BLOCK_SIZE); } - if (pdPASS != xTimerDelete(timer, 0)) /* delete timer ifself */ + err = MMC_WriteBlocks(&s_inst.card, write_buf, SD_START_BLOCK, SD_USE_BLOCK); + if (err != kStatus_Success) { - FSD_ERROR("Delete exit timer failed."); - exit_timer = NULL; + FSD_ERROR("eMMC write fail."); + goto write_read_exit; } - MMC_Deinit(&s_inst.card); - SDMMC_OSADeInit(); - FSdifTimingDeinit(); - - is_running = FALSE; -} - -static void eMMCSendEvent(u32 evt_bits) -{ - FASSERT(sync); - BaseType_t x_result = pdFALSE; - - FSD_DEBUG("Ack evt 0x%x", evt_bits); - x_result = xEventGroupSetBits(sync, evt_bits); -} - -static boolean eMMCWaitEvent(u32 evt_bits, TickType_t wait_delay) -{ - FASSERT(sync); - EventBits_t ev; - ev = xEventGroupWaitBits(sync, evt_bits, - pdTRUE, pdFALSE, wait_delay); /* wait for cmd/data done */ - if (ev & evt_bits) + err = MMC_ReadBlocks(&s_inst.card, read_buf, SD_START_BLOCK, SD_USE_BLOCK); + if (err == kStatus_Success) + { + if (memcmp(write_buf, read_buf, (SD_MAX_RW_BLK * SD_BLOCK_SIZE)) == 0) + { + taskENTER_CRITICAL(); + printf("write_buf...\r\n"); + FtDumpHexByte(write_buf, RESULT_DISPLAY_LEN); + printf("read_buf...\r\n"); + FtDumpHexByte(read_buf, RESULT_DISPLAY_LEN); + taskEXIT_CRITICAL(); + } + else + { + err = kStatus_Fail; + FSD_ERROR("write_buf != read_buf, eMMC write or read failed."); + goto write_read_exit; + } + } + else { - return TRUE; + FSD_ERROR("eMMC read fail."); + goto write_read_exit; } - return FALSE; +write_read_exit: + FSD_INFO("%s return with err: %d", __func__, err); + return err; } -static void eMMCInitTask(void *args) +static void SdifEmmcReadWriteTask(void) { - status_t err = 0; + FError err = kStatus_Success; + int task_res = SDIF_EXAMPLE_SUCCESS; - err = MMC_CfgInitialize(&s_inst, &s_inst_config); - if (kStatus_Success != err) + err = EmmcInit(); + if (err != kStatus_Success) { - FSD_ERROR("Init MMC failed, err = %d !!!", err); + task_res = SDIF_EXAMPLE_INIT_FAILURE; + FSD_ERROR("EmmcInit failed."); goto task_exit; } - eMMCSendEvent(SD_EVT_INIT_DONE); + err = EmmcWriteRead(); + if (err != kStatus_Success) + { + task_res = SDIF_EXAMPLE_WRITE_READ_FAILURE; + FSD_ERROR("EmmcWriteRead failed."); + goto task_exit; + } task_exit: - vTaskDelete(NULL); /* delete task itself */ -} + xQueueSend(xQueue, &task_res, 0); -static void eMMCWriteReadTask(void *args) -{ - u32 times = 0U; - const TickType_t wait_delay = pdMS_TO_TICKS(2000UL); /* wait for 2 seconds */ - FError err; - const uintptr trans_len = SD_USE_BLOCK * SD_BLOCK_SIZE; - - eMMCWaitEvent(SD_EVT_INIT_DONE, portMAX_DELAY); - - for (;;) + if (&s_inst.card != NULL) { - /* do read and write operation */ - { - printf("eMMC init success.\n"); - - for (u32 i = 0; i < SD_USE_BLOCK; i++) /* copy string to write buffer as each block */ - { - memset(rw_buf + i * SD_BLOCK_SIZE, (SD_START_BLOCK + i + 1), SD_BLOCK_SIZE); - } - - err = MMC_WriteBlocks(&s_inst.card, rw_buf, SD_START_BLOCK, SD_USE_BLOCK); - if (kStatus_Success != err) - { - FSD_ERROR("eMMC write fail."); - goto task_exit; - } - - memset(rw_buf, 0, sizeof(rw_buf)); - - err = MMC_ReadBlocks(&s_inst.card, rw_buf, SD_START_BLOCK, SD_USE_BLOCK); - if ((kStatus_Success == err)) - { - FtDumpHexByte(rw_buf, SD_BLOCK_SIZE * min((u32)2, (u32)SD_USE_BLOCK)); - printf("%s@%d: eMMC read and write example success !!! \r\n", __func__, __LINE__); - } - else - { - FSD_ERROR("eMMC read fail."); - goto task_exit; - } - } - - vTaskDelay(wait_delay); - - if (++times > run_times) - { - break; - } + MMC_Deinit(&s_inst.card); } + SDMMC_OSADeInit(); + FSdifTimingDeinit(); -task_exit: - printf("Exit from write task.\r\n"); - vTaskSuspend(NULL); /* suspend task */ + vTaskDelete(NULL); } -BaseType_t FFreeRTOSeMMCWriteRead(void) +int FFreeRTOSEmmcWriteRead(void) { - BaseType_t ret = pdPASS; - const TickType_t total_run_time = pdMS_TO_TICKS(30000UL); /* run for 10 secs deadline */ + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = SDIF_EXAMPLE_UNKNOWN_STATE; - if (is_running) + /* 进入操作任务前的准备工作 */ + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) { - FSD_ERROR("Task is running."); - return pdPASS; + FSD_ERROR("xQueue create failed."); + goto exit; } - FASSERT_MSG(NULL == sync, "Event group exists."); - FASSERT_MSG((sync = xEventGroupCreate()) != NULL, "Create event group failed."); - - is_running = TRUE; - FSdifTimingInit(); SDMMC_OSAInit(); @@ -229,37 +213,41 @@ BaseType_t FFreeRTOSeMMCWriteRead(void) s_inst_config.maxTransSize = SD_MAX_RW_BLK * SD_BLOCK_SIZE; s_inst_config.defBlockSize = SD_BLOCK_SIZE; s_inst_config.cardClock = MMC_CLOCK_52MHZ; - - ret = xTaskCreate((TaskFunction_t)eMMCInitTask, - (const char *)"eMMCInitTask", - (uint16_t)2048, - NULL, - (UBaseType_t)configMAX_PRIORITIES - 1, - NULL); - FASSERT_MSG(pdPASS == ret, "Create task failed."); - - ret = xTaskCreate((TaskFunction_t)eMMCWriteReadTask, - (const char *)"eMMCInitTask", - (uint16_t)2048, - NULL, - (UBaseType_t)configMAX_PRIORITIES - 2, - &write_task); - FASSERT_MSG(pdPASS == ret, "Create task failed."); - - exit_timer = xTimerCreate("Exit-Timer", /* Text name for the software timer - not used by FreeRTOS. */ - total_run_time, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - NULL, /* use timer id to pass task data for reference. */ - eMMCExitCallback); /* The callback function to be used by the software timer being created. */ - - FASSERT_MSG(NULL != exit_timer, "Create exit timer failed."); - - taskEXIT_CRITICAL(); /* allow schedule since task created */ + /* 创建主要操作任务 */ + xReturn = xTaskCreate((TaskFunction_t)SdifEmmcReadWriteTask, + (const char *)"SdifEmmcReadWriteTask", + (uint16_t)4096, + NULL, + (UBaseType_t)SDIF_EXAMPLE_TASK_PRIORITY, + NULL); + if (xReturn == pdFAIL) + { + FSD_ERROR("xTaskCreate SdifTFReadWriteTask failed."); + goto exit; + } - ret = xTimerStart(exit_timer, 0); /* start */ + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FSD_ERROR("xQueue receive timeout."); + goto exit; + } - FASSERT_MSG(pdPASS == ret, "Start exit timer failed."); +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } - return ret; + if (task_res != SDIF_EXAMPLE_SUCCESS) + { + printf("%s@%d: SDIF eMMC write and read example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return task_res; + } + else + { + printf("%s@%d: SDIF eMMC write and read example [success].\r\n", __func__, __LINE__); + return task_res; + } } \ No newline at end of file diff --git a/example/peripheral/sdif/src/sdif_tf_read_write.c b/example/peripheral/sdif/src/sdif_tf_read_write.c index 594c8b9e3a1fe7d4a698094bb056c3e0a941f0d1..2b294217f059b9b794404017cf5cfcbdfb9c6ac8 100644 --- a/example/peripheral/sdif/src/sdif_tf_read_write.c +++ b/example/peripheral/sdif/src/sdif_tf_read_write.c @@ -11,211 +11,191 @@ * See the Phytium Public License for more details. * * - * FilePath: sd_read_write.c + * FilePath: sdif_tf_read_write.c * Date: 2022-07-25 15:58:24 * LastEditTime: 2022-07-25 15:58:25 * Description:   This file is for providing functions used in cmd_sd.c file. * * Modify History: - * Ver   Who        Date         Changes - * ----- ------     --------    -------------------------------------- - * 1.0 zhugengyu 2022/8/26 first commit + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 zhugengyu 2022/8/26 first commit + * 2.0 liqiaozhong 2024/4/22 add no letter shell mode, adapt to auto-test system */ + /***************************** Include Files *********************************/ #include #include #include "FreeRTOS.h" #include "task.h" -#include "event_groups.h" +#include "queue.h" -#include "fassert.h" #include "fdebug.h" -#include "fsleep.h" #include "fkernel.h" -#include "fcache.h" -#include "fio.h" #include "fsdif_timing.h" #include "fsl_sdmmc.h" -#include "sdif_read_write.h" /************************** Constant Definitions *****************************/ -#define SD_EVT_INIT_DONE (0x1 << 0) -#define SD_EVT_WRITE_DONE (0x1 << 1) -#define SD_EVT_READ_DONE (0x1 << 2) +#define FSD_EXAMPLE_TAG "FSD_EXAMPLE" +#define FSD_ERROR(format, ...) FT_DEBUG_PRINT_E(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) +#define FSD_WARN(format, ...) FT_DEBUG_PRINT_W(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) +#define FSD_INFO(format, ...) FT_DEBUG_PRINT_I(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) +#define FSD_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) +#ifdef CONFIG_TARGET_PHYTIUMPI +#define SD_CONTROLLER_ID FSDIO0_ID +#else +#define SD_CONTROLLER_ID FSDIO1_ID +#endif + +/* user-define */ +#define SD_WORK_IRQ TRUE /* 0 for POLL mode, 1 for IRQ mode */ +#define SD_WORK_DMA TRUE /* 0 for PIO mode, 1 for DMA mode */ +#define SD_BLOCK_SIZE 512U +#define SD_START_BLOCK 0U +#define SD_USE_BLOCK 3U +#define RESULT_DISPLAY_LEN 64U /* 用于展示的结果长度 */ +#define SDIF_EXAMPLE_TASK_PRIORITY 3U +#define TIMER_OUT (pdMS_TO_TICKS(4000U)) + +#if SD_WORK_DMA +#define SD_MAX_RW_BLK 10U +#else +#define SD_MAX_RW_BLK 4U +#endif +/**************************** Type Definitions *******************************/ enum { - FSD_EXAMPLE_OK = 0, - FSD_EXAMPLE_NOT_YET_INIT, - FSD_EXAMPLE_INIT_FAILED, - FSD_EXAMPLE_INVALID_PARAM, - FSD_EXAMPLE_READ_WRITE_FAILED, + SDIF_EXAMPLE_SUCCESS = 0, + SDIF_EXAMPLE_UNKNOWN_STATE, + SDIF_EXAMPLE_INIT_FAILURE, + SDIF_EXAMPLE_WRITE_READ_FAILURE, }; -/**************************** Type Definitions *******************************/ - /************************** Variable Definitions *****************************/ static sdmmchost_config_t s_inst_config; -static sdmmc_sd_t s_inst; +static sdmmc_sd_t s_inst; -static EventGroupHandle_t sync = NULL; -static TaskHandle_t write_task = NULL; -static TimerHandle_t exit_timer = NULL; -static boolean is_running = FALSE; -static u32 run_times = 1U; +static QueueHandle_t xQueue = NULL; -uint8_t s_dma_buffer[SZ_1M * 4] = {0}; -u8 rw_buf[SD_MAX_RW_BLK * SD_BLOCK_SIZE] __attribute((aligned(SD_BLOCK_SIZE))) = {0}; +static u8 write_buf[SD_MAX_RW_BLK * SD_BLOCK_SIZE] __attribute((aligned(SD_BLOCK_SIZE))) = {0}; +static u8 read_buf[SD_MAX_RW_BLK * SD_BLOCK_SIZE] __attribute((aligned(SD_BLOCK_SIZE))) = {0}; /***************** Macros (Inline Functions) Definitions *********************/ -#define FSD_EXAMPLE_TAG "FSD_EXAMPLE" -#define FSD_ERROR(format, ...) FT_DEBUG_PRINT_E(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) -#define FSD_WARN(format, ...) FT_DEBUG_PRINT_W(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) -#define FSD_INFO(format, ...) FT_DEBUG_PRINT_I(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) -#define FSD_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSD_EXAMPLE_TAG, format, ##__VA_ARGS__) + /************************** Function Prototypes ******************************/ /*****************************************************************************/ -static void TfExitCallback(TimerHandle_t timer) +static status_t TfInit(void) { - FError err = FT_SUCCESS; - printf("Exiting.....\r\n"); + status_t err = kStatus_Success; - if (write_task) + err = SD_CfgInitialize(&s_inst, &s_inst_config); + if (err != kStatus_Success) { - vTaskDelete(write_task); - write_task = NULL; + FSD_ERROR("Init SD failed, err = %d !!!", err); + goto task_exit; } - if (sync) +task_exit: + FSD_INFO("%s return with err: %d", __func__, err); + return err; +} + +static status_t TfWriteRead(void) +{ + status_t err = kStatus_Success; + + memset(write_buf, 0, sizeof(write_buf)); + memset(read_buf, 0, sizeof(write_buf)); + + for (u32 i = 0; i < SD_USE_BLOCK; i++) /* copy string to write buffer as each block */ { - vEventGroupDelete(sync); - sync = NULL; + memset((write_buf + i * SD_BLOCK_SIZE), (SD_START_BLOCK + i + 1), SD_BLOCK_SIZE); } - if (pdPASS != xTimerDelete(timer, 0)) /* delete timer ifself */ + err = SD_WriteBlocks(&s_inst.card, write_buf, SD_START_BLOCK, SD_USE_BLOCK); + if (err != kStatus_Success) { - FSD_ERROR("Delete exit timer failed."); - exit_timer = NULL; + FSD_ERROR("TF card write fail."); + goto write_read_exit; } - SD_Deinit(&s_inst.card); - SDMMC_OSADeInit(); - FSdifTimingDeinit(); - - is_running = FALSE; -} - -static void TfSendEvent(u32 evt_bits) -{ - FASSERT(sync); - BaseType_t x_result = pdFALSE; - - FSD_DEBUG("Ack evt 0x%x", evt_bits); - x_result = xEventGroupSetBits(sync, evt_bits); -} - -static boolean SDTfWaitEvent(u32 evt_bits, TickType_t wait_delay) -{ - FASSERT(sync); - EventBits_t ev; - ev = xEventGroupWaitBits(sync, evt_bits, - pdTRUE, pdFALSE, wait_delay); /* wait for cmd/data done */ - if (ev & evt_bits) + err = SD_ReadBlocks(&s_inst.card, read_buf, SD_START_BLOCK, SD_USE_BLOCK); + if (err == kStatus_Success) + { + if (memcmp(write_buf, read_buf, (SD_MAX_RW_BLK * SD_BLOCK_SIZE)) == 0) + { + taskENTER_CRITICAL(); + printf("write_buf...\r\n"); + FtDumpHexByte(write_buf, RESULT_DISPLAY_LEN); + printf("read_buf...\r\n"); + FtDumpHexByte(read_buf, RESULT_DISPLAY_LEN); + taskEXIT_CRITICAL(); + } + else + { + err = kStatus_Fail; + FSD_ERROR("write_buf != read_buf, TF card write or read failed."); + goto write_read_exit; + } + } + else { - return TRUE; + FSD_ERROR("TF card read fail."); + goto write_read_exit; } - return FALSE; +write_read_exit: + FSD_INFO("%s return with err: %d", __func__, err); + return err; } -static void TfInitTask(void *args) +static void SdifTFReadWriteTask(void) { - status_t err = 0; + FError err = kStatus_Success; + int task_res = SDIF_EXAMPLE_SUCCESS; - err = SD_CfgInitialize(&s_inst, &s_inst_config); - if (kStatus_Success != err) + err = TfInit(); + if (err != kStatus_Success) { - FSD_ERROR("Init SD failed, err = %d !!!", err); + task_res = SDIF_EXAMPLE_INIT_FAILURE; + FSD_ERROR("TfInit() failed."); goto task_exit; } - TfSendEvent(SD_EVT_INIT_DONE); + err = TfWriteRead(); + if (err != kStatus_Success) + { + task_res = SDIF_EXAMPLE_WRITE_READ_FAILURE; + FSD_ERROR("TfWriteRead() failed."); + goto task_exit; + } task_exit: - vTaskDelete(NULL); /* delete task itself */ -} - -static void TfWriteReadTask(void *args) -{ - u32 times = 0U; - const TickType_t wait_delay = pdMS_TO_TICKS(2000UL); /* wait for 2 seconds */ - FError err; - const uintptr trans_len = SD_USE_BLOCK * SD_BLOCK_SIZE; - - SDTfWaitEvent(SD_EVT_INIT_DONE, portMAX_DELAY); - - for (;;) + if (&s_inst.card != NULL) { - /* do read and write operation */ - { - printf("TF card init success.\n"); - - for (u32 i = 0; i < SD_USE_BLOCK; i++) /* copy string to write buffer as each block */ - { - memset(rw_buf + i * SD_BLOCK_SIZE, (SD_START_BLOCK + i + 1), SD_BLOCK_SIZE); - } - - err = SD_WriteBlocks(&s_inst.card, rw_buf, SD_START_BLOCK, SD_USE_BLOCK); - if (kStatus_Success != err) - { - FSD_ERROR("TF card write fail."); - goto task_exit; - } - - memset(rw_buf, 0, sizeof(rw_buf)); - - err = SD_ReadBlocks(&s_inst.card, rw_buf, SD_START_BLOCK, SD_USE_BLOCK); - if ((kStatus_Success == err)) - { - FtDumpHexByte(rw_buf, SD_BLOCK_SIZE * min((u32)2, (u32)SD_USE_BLOCK)); - printf("%s@%d: TF card read and write example success !!! \r\n", __func__, __LINE__); - } - else - { - FSD_ERROR("TF card read fail."); - goto task_exit; - } - } - - vTaskDelay(wait_delay); - - if (++times > run_times) - { - break; - } + SD_Deinit(&s_inst.card); } + SDMMC_OSADeInit(); + FSdifTimingDeinit(); -task_exit: - printf("Exit from write task.\r\n"); - vTaskSuspend(NULL); /* suspend task */ + xQueueSend(xQueue, &task_res, 0); + vTaskDelete(NULL); } -BaseType_t FFreeRTOSTfWriteRead(void) +int FFreeRTOSTfWriteRead(void) { - BaseType_t ret = pdPASS; - const TickType_t total_run_time = pdMS_TO_TICKS(30000UL); /* run for 10 secs deadline */ + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = SDIF_EXAMPLE_UNKNOWN_STATE; - if (is_running) + /* 进入操作任务前的准备工作 */ + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) { - FSD_ERROR("Task is running."); - return pdPASS; + FSD_ERROR("xQueue create failed."); + goto exit; } - FASSERT_MSG(NULL == sync, "Event group exists."); - FASSERT_MSG((sync = xEventGroupCreate()) != NULL, "Create event group failed."); - - is_running = TRUE; - FSdifTimingInit(); SDMMC_OSAInit(); @@ -234,36 +214,40 @@ BaseType_t FFreeRTOSTfWriteRead(void) s_inst_config.cardClock = SD_CLOCK_50MHZ; s_inst_config.isUHSCard = FALSE; - ret = xTaskCreate((TaskFunction_t)TfInitTask, - (const char *)"TfInitTask", - (uint16_t)2048, - NULL, - (UBaseType_t)configMAX_PRIORITIES - 1, - NULL); - FASSERT_MSG(pdPASS == ret, "Create task failed."); - - ret = xTaskCreate((TaskFunction_t)TfWriteReadTask, - (const char *)"TfWriteReadTask", - (uint16_t)2048, - NULL, - (UBaseType_t)configMAX_PRIORITIES - 2, - &write_task); - - FASSERT_MSG(pdPASS == ret, "Create task failed."); - - exit_timer = xTimerCreate("Exit-Timer", /* Text name for the software timer - not used by FreeRTOS. */ - total_run_time, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - NULL, /* use timer id to pass task data for reference. */ - TfExitCallback); /* The callback function to be used by the software timer being created. */ - - FASSERT_MSG(NULL != exit_timer, "Create exit timer failed."); - - taskEXIT_CRITICAL(); /* allow schedule since task created */ + /* 创建主要操作任务 */ + xReturn = xTaskCreate((TaskFunction_t)SdifTFReadWriteTask, + (const char *)"SdifTFReadWriteTask", + (uint16_t)4096, + NULL, + (UBaseType_t)SDIF_EXAMPLE_TASK_PRIORITY, + NULL); + if (xReturn == pdFAIL) + { + FSD_ERROR("xTaskCreate SdifTFReadWriteTask failed."); + goto exit; + } - ret = xTimerStart(exit_timer, 0); /* start */ + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FSD_ERROR("xQueue receive timeout."); + goto exit; + } - FASSERT_MSG(pdPASS == ret, "Start exit timer failed."); +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } - return ret; + if (task_res != SDIF_EXAMPLE_SUCCESS) + { + printf("%s@%d: SDIF TF card write and read example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return task_res; + } + else + { + printf("%s@%d: SDIF TF card write and read example [success].\r\n", __func__, __LINE__); + return task_res; + } } \ No newline at end of file diff --git a/example/peripheral/spi/main.c b/example/peripheral/spi/main.c index 291f53e564a5237276db2ba9fc27b2929b59baab..4286392e93e8982f097705bd7fba40d952b93a8b 100644 --- a/example/peripheral/spi/main.c +++ b/example/peripheral/spi/main.c @@ -31,7 +31,7 @@ #else #include "task.h" #include "sfud_read_write.h" - +#define SFUD_EXAMPLE_TASK_PRIORITY 2 void SfudExampleTaskEntry(void) { /*Demo read and write by sfud*/ @@ -60,7 +60,7 @@ int main(void) (const char *)"SfudExampleTaskEntry",/* 任务名字 */ (uint16_t)4096, /* 任务栈大小 */ NULL,/* 任务入口函数参数 */ - (UBaseType_t)2, /* 任务的优先级 */ + (UBaseType_t)SFUD_EXAMPLE_TASK_PRIORITY, /* 任务的优先级 */ NULL); taskEXIT_CRITICAL(); /*退出临界区*/ diff --git a/example/peripheral/spi/src/sfud_read_write.c b/example/peripheral/spi/src/sfud_read_write.c index f77db1e55d92d1c4a4f1b8b539f72cfed1768e50..0cfac52ddbc708786df9a55cd1696cd04e2b342e 100644 --- a/example/peripheral/spi/src/sfud_read_write.c +++ b/example/peripheral/spi/src/sfud_read_write.c @@ -44,7 +44,7 @@ static QueueHandle_t xQueue = NULL; /***************** Macros (Inline Functions) Definitions *********************/ #define TIMER_OUT ( pdMS_TO_TICKS( 3000UL ) ) - +#define SFUD_WR_TEST_TASK_PRIORITY 3 #define FSPIM_DEBUG_TAG "SFUD-DEMO" #define FSPIM_ERROR(format, ...) FT_DEBUG_PRINT_E(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__) #define FSPIM_WARN(format, ...) FT_DEBUG_PRINT_W(FSPIM_DEBUG_TAG, format, ##__VA_ARGS__) @@ -261,7 +261,7 @@ BaseType_t FFreeRTOSSfudWriteThenRead(void) (const char *)"SpiSfudWriteThenReadTask",/* 任务名字 */ (uint16_t)4096, /* 任务栈大小 */ NULL,/* 任务入口函数参数 */ - (UBaseType_t)2, /* 任务的优先级 */ + (UBaseType_t)SFUD_WR_TEST_TASK_PRIORITY, /* 任务的优先级 */ NULL); if (xReturn == pdFAIL) { diff --git a/example/peripheral/timer_tacho/README.md b/example/peripheral/timer_tacho/README.md index bfdc16b5693d77f1a3406922c905c58b67c3c335..c5b46d3ea1d0077fa8a7d6dd022e941bfa13cc2c 100644 --- a/example/peripheral/timer_tacho/README.md +++ b/example/peripheral/timer_tacho/README.md @@ -3,15 +3,16 @@ ## 1. 例程介绍 本例程示范了freertos环境下的timer、tacho和capture的使用,包括timer控制器的初始化、定时、信号捕捉操作; -程序启动后,创建timer、tacho或capture(两者使用同一IO,默认tacho,变更需要更改初始化和任务)的初始化任务,分别测试定时功能,采样转换功能,以及脉冲计数触发功能; +程序启动后,创建timer、tacho或capture(两者使用同一IO,默认tacho,若想使用capture功能,则参照tacho测试步骤初始化即可)任务,分别测试定时功能,采样转换功能,以及脉冲计数触发功能; 例程仅仅支持E2000上使用; E2000DQ上使用的demo板上的 PWM-IN12(tacho—in12) 进行测试。 + ## 2. 如何使用例程 本例程需要用到 - Phytium开发板(E2000DQ of demo板) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -26,7 +27,7 @@ E2000DQ上使用的demo板上的 PWM-IN12(tacho—in12) 进行测试。 ### 2.1.1 硬件连线 -- E2000 pwm_in12使用1KHz的方波 +- E2000 pwm_in12使用1KHz的方波,也即J30上,右内侧第三脚接入示波器或其他信号源方波信号,如下图所示 ![hardware_e2000](./figs/tacho_hdw.png) @@ -111,8 +112,7 @@ bootelf -p 0x90100000 ![e2000d](./figs/timer_tacho.png) - 图中我们使用timer id 0 作为定时器任务的控制器,time in 的数字表示进入循环定时中断服务的次数。 -- get captureCnt表示使用timer id 12控制器来采集脉冲的个数(设置上升沿捕获) -- tachometer id使用timer id 12控制器来抓取1KHz信号来模拟风扇波形信号。RPM表示转速 +- RPM表示转速 ## 3. 如何解决问题 diff --git a/example/peripheral/timer_tacho/figs/timer_capture.png b/example/peripheral/timer_tacho/figs/timer_capture.png index be579323637c5aed38ca6d5781ad51f6d60354b3..d46001e2b300e9349737ef3f758cae2d8abe2977 100644 Binary files a/example/peripheral/timer_tacho/figs/timer_capture.png and b/example/peripheral/timer_tacho/figs/timer_capture.png differ diff --git a/example/peripheral/timer_tacho/figs/timer_tacho.png b/example/peripheral/timer_tacho/figs/timer_tacho.png index ac6729b4d558dd755b0eb6d7e145b4f8da6fdf13..b051cd8463926c73080c003517736243b62ec246 100644 Binary files a/example/peripheral/timer_tacho/figs/timer_tacho.png and b/example/peripheral/timer_tacho/figs/timer_tacho.png differ diff --git a/example/peripheral/timer_tacho/main.c b/example/peripheral/timer_tacho/main.c index 441ec31d17f43069774e89bc31dc258f9411b1eb..ee47d0ccea7cc61a11871deef82fdc46e25f681f 100644 --- a/example/peripheral/timer_tacho/main.c +++ b/example/peripheral/timer_tacho/main.c @@ -20,33 +20,60 @@ * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 liushengming 2022/11/25 init + * 2.0 wangzq 2024/4/29 add no letter shell mode, adapt to auto-test system */ #include + +#include "FreeRTOS.h" + +#include "sdkconfig.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" +#else +#include "task.h" #include "timer_tacho_example.h" -int main(void) +#define TIMER_TACHO_EXAMPLE_TASK_PRIORITY 2 + +void TimerTachoExampleTaskEntry() { - BaseType_t ret; + /* example functions */ + FFreeRTOSTimerTachoCreate(); - ret = FFreeRTOSTimerTachoCreate(); - if (ret != pdPASS) - { - goto FAIL_EXIT; - } + /* end flag */ + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif + +int main(void) +{ + BaseType_t ret = pdPASS; +#ifdef CONFIG_USE_LETTER_SHELL ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)TimerTachoExampleTaskEntry, /* 任务入口函数 */ + (const char *)"TimerTachoExampleTaskEntry", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)TIMER_TACHO_EXAMPLE_TASK_PRIORITY, /* 任务优先级 */ + NULL); /* 任务句柄 */ +#endif if (ret != pdPASS) { goto FAIL_EXIT; } - vTaskStartScheduler(); /* 启动任务,开启调度 */ + /* 启动任务,开启调度 */ + vTaskStartScheduler(); while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("Failed,the ret value is 0x%x. \r\n", ret); + printf("Timer_tacho example failed in main.c, the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/peripheral/timer_tacho/src/cmd_timer_tacho.c b/example/peripheral/timer_tacho/src/cmd_timer_tacho.c new file mode 100644 index 0000000000000000000000000000000000000000..cab6555562949dc1e13e61fa5efe27ac86614bcf --- /dev/null +++ b/example/peripheral/timer_tacho/src/cmd_timer_tacho.c @@ -0,0 +1,70 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: cmd_timer_tacho.c + * Date: 2022-06-28 14:42:53 + * LastEditTime: 2022-06-28 14:42:53 + * Description:  This file is for timer tacho shell command implmentation. + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 2.0 wangzq 2024/4/22 add no letter shell mode, adapt to auto-test system + */ +/***************************** Include Files *********************************/ +#include +#include +#include "strto.h" +#include "sdkconfig.h" + +#include "FreeRTOS.h" + +#ifdef CONFIG_USE_LETTER_SHELL +#include "../src/shell.h" +#include "timer_tacho_example.h" +/************************** Constant Definitions *****************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ + +static void TimerTachoCmdUsage(void) +{ + printf("Usage:\r\n"); + printf("timer tacho\r\n"); + printf("-- Demo to test timer and tacho \r\n"); +} +static int TimerTachoCmdEntry(int argc, char *argv[]) +{ + int ret = 0; + + if (argc < 2) + { + TimerTachoCmdUsage(); + return -1; + } + if (!strcmp(argv[1], "tacho")) + { + ret = FFreeRTOSTimerTachoCreate(); + } + + return ret; +} +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), timer, TimerTachoCmdEntry, test freertos timer_tacho driver); + +#endif /* CONFIG_USE_LETTER_SHELL */ + diff --git a/example/peripheral/timer_tacho/src/timer_tacho_example.c b/example/peripheral/timer_tacho/src/timer_tacho_example.c index 0b817b51ef01ba09b6de4bbbb91a8f1a50e87a65..76c70a9d578f6731007abbe79a4b55620033da02 100644 --- a/example/peripheral/timer_tacho/src/timer_tacho_example.c +++ b/example/peripheral/timer_tacho/src/timer_tacho_example.c @@ -36,32 +36,59 @@ #include "sdkconfig.h" #include "fdebug.h" -/* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 50000UL ) ) -#define TIMER_IRQ_PRIORITY 0xb -#define TACHO_IRQ_PRIORITY 0xc -#define TIMER_INSTANCE_NUM 0U - -#ifdef CONFIG_TARGET_PHYTIUMPI -#define TACHO_INSTANCE_NUM 3U +/************************** Constant Definitions *****************************/ +#ifdef CONFIG_FIREFLY_DEMO_BOARD + #define TACHO_INSTANCE_NUM 3U #else -#define TACHO_INSTANCE_NUM 12U + #define TACHO_INSTANCE_NUM 12U #endif +#define TIMER_TACHO_TEST_TASK_PRIORITY 3 + +static QueueHandle_t xQueue = NULL; +static boolean is_running = FALSE; +/* The periods assigned to time out */ +#define TIMER_OUT (pdMS_TO_TICKS(50000UL)) +#define TIMER_IRQ_PRIORITY 0xb +#define TACHO_IRQ_PRIORITY 0xc +#define TIMER_INSTANCE_NUM 0U /* write and read task delay in milliseconds */ #define TASK_DELAY_MS 2000UL - -static xTaskHandle timer_handle; -static xTaskHandle tacho_handle; -static xTaskHandle cap_handle; -static xTaskHandle init_handle; - +/**************************** Type Definitions *******************************/ +enum +{ + TIMER_TACHO_TEST_SUCCESS = 0, + TIMER_TACHO_TEST_UNKNOWN = 1, + TIMER_TACHO_INIT_ERROR = 2, + TIMER_TACHO_TEST_ERROR = 3, +}; +/************************** Variable Definitions *****************************/ static FFreeRTOSTimerTacho *os_timer_ctrl; static FFreeRTOSTimerTacho *os_tacho_ctrl; volatile int timerflag = 0; volatile int tachoflag = 0; +/***************** Macros (Inline Functions) Definitions *********************/ +#define FTIMER_TACHO_DEBUG_TAG "TIMER-TACHO" +#define FTIMER_TACHO_ERROR(format, ...) FT_DEBUG_PRINT_E(FTIMER_TACHO_DEBUG_TAG, format, ##__VA_ARGS__) +#define FTIMER_TACHO_WARN(format, ...) FT_DEBUG_PRINT_W(FTIMER_TACHO_DEBUG_TAG, format, ##__VA_ARGS__) +#define FTIMER_TACHO_INFO(format, ...) FT_DEBUG_PRINT_I(FTIMER_TACHO_DEBUG_TAG, format, ##__VA_ARGS__) +#define FTIMER_TACHO_DEBUG(format, ...) FT_DEBUG_PRINT_D(FTIMER_TACHO_DEBUG_TAG, format, ##__VA_ARGS__) + + +/*exit the timer tacho example task and deinit the gpio */ +static void TimerTachoExit(void) +{ + printf("Exiting...\r\n"); + /* deinit iomux */ + FIOMuxDeInit(); + FFreeRTOSTachoDeinit(os_tacho_ctrl); + os_tacho_ctrl = NULL; + FFreeRTOSTimerDeinit(os_timer_ctrl); + os_timer_ctrl = NULL; + is_running = FALSE; +} /***** timer intr and handler******/ /** @@ -219,130 +246,95 @@ void TachoEnableIntr(FTimerTachoCtrl *instance_p) return; } -static void TimerTask(void *pvParameters) +/*tacho test function*/ +static FError TachoTest(void) { + FError ret = FT_SUCCESS; + u32 rpm; TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FREERTOS_TIMER_TACHO_SUCCESS; - FFreeRTOSTimerTacho *timer_p = (FFreeRTOSTimerTacho *)pvParameters; - vTaskDelay(xDelay); - printf("\r\n*****TimerTask is running...\r\n"); - - TimerEnableIntr(&os_timer_ctrl->ctrl); - ret = FFreeRTOSTimerStart(timer_p); - if (ret != FREERTOS_TIMER_TACHO_SUCCESS) - { - printf("TimerTask Start failed.\r\n"); - return; - } - - xDelay = pdMS_TO_TICKS(10000);/*delay 10s*/ - vTaskDelay(xDelay); - - ret = FFreeRTOSTimerStop(timer_p); - if (ret != FREERTOS_TIMER_TACHO_SUCCESS) - { - printf("TimerTask Stop failed.\r\n"); - return; - } - - /* disable timer irq */ - TimerDisableIntr(&os_timer_ctrl->ctrl); - FFreeRTOSTimerDeinit(timer_p); - printf("***TimerTask is over.\r\n"); - vTaskDelete(NULL); -} - -static void TachoTask(void *pvParameters) -{ - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FFreeRTOSTimerTacho *tacho_p = (FFreeRTOSTimerTacho *)pvParameters; - FError ret = FREERTOS_TIMER_TACHO_SUCCESS; vTaskDelay(xDelay); printf("\r\n*****TachoTask is running...\r\n"); + TachoEnableIntr(&os_tacho_ctrl->ctrl); + ret = FFreeRTOSTimerStart(os_tacho_ctrl); - TachoEnableIntr(&tacho_p->ctrl); - ret = FFreeRTOSTimerStart(tacho_p); - u32 rpm; vTaskDelay(100);/*等待采样周期完成*/ - if (ret != FREERTOS_TIMER_TACHO_SUCCESS) + if (ret != FT_SUCCESS) { - printf("Tacho start failed.\r\n"); - return; + ret = TIMER_TACHO_TEST_ERROR; + goto exit; } for (size_t i = 0; i < 5; i++) { - ret = FFreeRTOSTachoGetRPM(tacho_p, &rpm); - if (ret != FREERTOS_TIMER_TACHO_SUCCESS) + ret = FFreeRTOSTachoGetRPM(os_tacho_ctrl, &rpm); + if (ret != FT_SUCCESS) { printf("TachoTask Stop failed.\r\n"); - return; + goto exit; } printf("***GET_RPM:%d.\r\n", rpm); vTaskDelay(xDelay);/*Collect every 2 seconds*/ } - TachoDisableIntr(&tacho_p->ctrl); - FFreeRTOSTimerStop(tacho_p); - FFreeRTOSTachoDeinit(tacho_p); - /*deinit iomux */ - FIOMuxDeInit(); -tacho_task_exit: - printf("***TachoTask over.\r\n"); - vTaskDelete(NULL); +exit: + /* disable tacho irq */ + TachoDisableIntr(&os_tacho_ctrl->ctrl); + /* disable tacho */ + FFreeRTOSTachoDeinit(os_tacho_ctrl); + return ret; } -static void captask(void *pvParameters) +/*timer test function*/ +static FError TimerTest(void) { - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FFreeRTOSTimerTacho *cap_p = (FFreeRTOSTimerTacho *)pvParameters; - FError ret = FREERTOS_TIMER_TACHO_SUCCESS; - vTaskDelay(pdMS_TO_TICKS(1)); - - printf("\r\n*****TimerCapTask is running...\r\n"); + FError ret = FT_SUCCESS; + TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); + vTaskDelay(xDelay); + printf("\r\n*****TimerTask is running...\r\n"); - TachoEnableIntr(&cap_p->ctrl); - ret = FFreeRTOSTimerStart(cap_p); - if (ret != FREERTOS_TIMER_TACHO_SUCCESS) + TimerEnableIntr(&os_timer_ctrl->ctrl); + ret = FFreeRTOSTimerStart(os_timer_ctrl); + if (ret != FT_SUCCESS) { - printf("Tacho start failed.\r\n"); - goto tacho_task_exit; + ret = TIMER_TACHO_TEST_ERROR; + goto exit; } - for (size_t i = 0; i < 5; i++) + xDelay = pdMS_TO_TICKS(10000);/*delay 10s*/ + vTaskDelay(xDelay); + ret = FFreeRTOSTimerStop(os_timer_ctrl); + if (ret != FT_SUCCESS) { - printf("Get id %d CaptureCnt is :%d.\r\n", cap_p->ctrl.config.id, FFreeRTOSTachoGetCNT(cap_p)); - vTaskDelay(pdMS_TO_TICKS(1)); + ret = TIMER_TACHO_TEST_ERROR; + goto exit; } - /* disable tacho irq */ - TachoDisableIntr(&cap_p->ctrl); - FFreeRTOSTimerStop(cap_p); - FFreeRTOSTachoDeinit(cap_p); -tacho_task_exit: - printf("TimerCapTask is over.\r\n"); - vTaskDelete(NULL); +exit: + /* disable timer irq */ + TimerDisableIntr(&os_timer_ctrl->ctrl); + /* disable timer */ + FFreeRTOSTimerDeinit(os_timer_ctrl); + return ret; } -static void InitTask(void *pvParameters) +/*timer init function*/ +static FError TimerInit(void) { - BaseType_t xReturn = pdPASS; - /* init timers controller */ - + FError ret = FT_SUCCESS; os_timer_ctrl = FFreeRTOSTimerInit(TIMER_INSTANCE_NUM, FTIMER_CYC_CMP, 2000000);/* 2000000 us = 2 s */ + if (os_timer_ctrl == NULL) { - printf("*Timer init error.\r\n"); - goto timer_init_exit; + ret = TIMER_TACHO_INIT_ERROR; + goto exit; } FTimerRegisterEvtCallback(&os_timer_ctrl->ctrl, FTIMER_EVENT_CYC_CMP, CycCmpIntrHandler); FTimerRegisterEvtCallback(&os_timer_ctrl->ctrl, FTIMER_EVENT_ONCE_CMP, OnceCmpIntrHandler); FTimerRegisterEvtCallback(&os_timer_ctrl->ctrl, FTIMER_EVENT_ROLL_OVER, RolloverIntrHandler); - /*init mode: FTIMER_WORK_MODE_CAPTURE or FTIMER_WORK_MODE_TACHO */ os_tacho_ctrl = FFreeRTOSTachoInit(TACHO_INSTANCE_NUM, FTIMER_WORK_MODE_TACHO); - if (os_timer_ctrl == NULL) + if (os_tacho_ctrl == NULL) { - printf("*Tacho init error.\r\n"); - goto timer_init_exit; + ret = TIMER_TACHO_INIT_ERROR; + goto exit; } /*init iomux*/ FIOMuxInit(); @@ -353,25 +345,42 @@ static void InitTask(void *pvParameters) FTimerRegisterEvtCallback(&os_tacho_ctrl->ctrl, FTACHO_EVENT_UNDER, TachUnderIntrHandler); FTimerRegisterEvtCallback(&os_tacho_ctrl->ctrl, FTACHO_EVENT_CAPTURE, CapIntrHandler); - taskENTER_CRITICAL(); //进入临界区 - xReturn = xTaskCreate((TaskFunction_t)TimerTask, /* 任务入口函数 */ - (const char *)"TimerTask", /* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - (void *)os_timer_ctrl, /* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ - (TaskHandle_t *)&timer_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "TimerTask create is failed."); - - xReturn = xTaskCreate((TaskFunction_t)TachoTask, /* 任务入口函数 */ - (const char *)"TachoTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - (void *)os_tacho_ctrl,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 2, /* 任务的优先级 */ - (TaskHandle_t *)&tacho_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "TachoTask create is failed."); - - taskEXIT_CRITICAL(); //退出临界区 -timer_init_exit: +exit: + return ret; +} + +/*timer tacho test task*/ +static void TimerTachoTask(void) +{ + int task_res = TIMER_TACHO_TEST_SUCCESS; + FError ret = FT_SUCCESS; + ret = TimerInit(); + + if (ret != FT_SUCCESS) + { + FTIMER_TACHO_ERROR("TimerTachoTask failed."); + task_res = TIMER_TACHO_INIT_ERROR; + goto task_exit; + } + /* create timer test */ + ret = TimerTest(); + if (ret != FT_SUCCESS) + { + FTIMER_TACHO_ERROR("TimerTest failed."); + task_res = TIMER_TACHO_TEST_ERROR; + goto task_exit; + } + /* create tacho test */ + ret = TachoTest(); + if (ret != FT_SUCCESS) + { + FTIMER_TACHO_ERROR("TachoTest failed."); + task_res = TIMER_TACHO_TEST_ERROR; + goto task_exit; + } + +task_exit: + xQueueSend(xQueue, &task_res, 0); vTaskDelete(NULL); } @@ -379,20 +388,54 @@ BaseType_t FFreeRTOSTimerTachoCreate(void) { BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - taskENTER_CRITICAL(); //进入临界区 - + int task_res = TIMER_TACHO_TEST_UNKNOWN; + if (is_running) + { + FTIMER_TACHO_ERROR("The task is running."); + return pdPASS; + } + is_running = TRUE; /* init timers controller */ + xQueue = xQueueCreate(1, sizeof(int)); /* create queue for task communication */ + if (xQueue == NULL) + { + FTIMER_TACHO_ERROR("xQueue create failed."); + goto exit; + } - xReturn = xTaskCreate((TaskFunction_t)InitTask, /* 任务入口函数 */ - (const char *)"InitTask",/* 任务名字 */ + xReturn = xTaskCreate((TaskFunction_t)TimerTachoTask, /* 任务入口函数 */ + (const char *)"TimerTachoTask",/* 任务名字 */ (uint16_t)1024, /* 任务栈大小 */ (void *)NULL,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ - (TaskHandle_t *)&init_handle); /* 任务控制 */ - FASSERT_MSG(xReturn == pdPASS, "TachoTask create is failed."); + (UBaseType_t)TIMER_TACHO_TEST_TASK_PRIORITY, /* 任务的优先级 */ + NULL); /* 任务句柄 */ + if (xReturn == pdFAIL) + { + FTIMER_TACHO_ERROR("xTaskCreate TimerTachoTask failed."); + goto exit; + } + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FTIMER_TACHO_ERROR("xQueue receive timeout."); + goto exit; + } - taskEXIT_CRITICAL(); //退出临界区 +exit: + if (xQueue != NULL) + { + vQueueDelete(xQueue); + } - return xReturn; + if (task_res != TIMER_TACHO_TEST_SUCCESS) + { + printf("%s@%d: Timer tacho example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return pdFAIL; + } + else + { + printf("%s@%d: Timer tacho example [success].\r\n", __func__, __LINE__); + return pdTRUE; + } } diff --git a/example/peripheral/wdt/README.md b/example/peripheral/wdt/README.md index 932f805d25c5fe755ccf48760a95561f5c1f8920..43dd662b747875e5910a7580fecda339f141d9e9 100644 --- a/example/peripheral/wdt/README.md +++ b/example/peripheral/wdt/README.md @@ -2,18 +2,13 @@ ## 1. 例程介绍 -本例程示范了freertos环境下的wdt的使用,包括看门狗的初始化、喂狗和去初始化操作; -程序启动后,创建消息队列用于超时中断消息传递,创建wdt初始化任务,指定超时中断处理函数; -创建消息队列接收任务FFreertosWdtQueueReceiveTask,用于接收超时中断处理函数发送的消息队列; -创建主动喂狗任务FFreertosWdtFeedTask,用于定时主动喂狗,这个周期比中断超时时间短; -创建单次模式的软件定时器,回调函数为删除FFreertosWdtFeedTask; -创建周期模式的软件定时器,定时获取wdt超时的倒计时,并在累计计数后,去初始化wdt,删除FFreertosWdtQueueReceiveTask和软件定时器; +本例程示范了freertos环境下的wdt的使用,包括看门狗的初始化、喂狗和去初始化操作,默认喂3次狗后停止看门狗控制器 ## 2. 如何使用例程 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PhytiumPi) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -47,12 +42,12 @@ - CONFIG_FREERTOS_USE_WDT 本例子已经提供好具体的编译指令,以下进行介绍: -- make 将目录下的工程进行编译 -- make clean 将目录下的工程进行清理 -- make image 将目录下的工程进行编译,并将生成的elf 复制到目标地址 -- make list_kconfig 当前工程支持哪些配置文件 -- make load_kconfig LOAD_CONFIG_NAME= 将预设配置加载至工程中 -- make menuconfig 配置目录下的参数变量 +- make 将目录下的工程进行编译 +- make clean 将目录下的工程进行清理 +- make image 将目录下的工程进行编译,并将生成的elf 复制到目标地址 +- make list_kconfig 当前工程支持哪些配置文件 +- make load_kconfig LOAD_CONFIG_NAME= 将预设配置加载至工程中 +- make menuconfig 配置目录下的参数变量 - make backup_kconfig 将目录下的sdkconfig 备份到./configs下 具体使用方法为: @@ -83,15 +78,9 @@ bootelf -p 0x90100000 ### 2.4 输出与实验现象 -- 系统进入后,创建wdt初始化任务,创建消息队列接收任务和主动喂狗任务,并创建单次模式和周期模式软件定时器,主动喂狗任务正常运行 +- 系统进入后,创建wdt喂狗任务,喂3次够后停止看门狗控制器 -![create](./figs/create.png) - -- 定时器时间到,触发单次模式软件定时器的回调函数,删除主动喂狗任务; -这个时候由于没有了主动喂狗,超时中断会触发,中断处理函数中发送消息队列,消息队列接收任务正常接收后处理数据; -周期模式软件定时器累计计数到30s后,去初始化wdt,删除消息队列接收任务,删除软件定时器 - -![delete](./figs/delete.png) +![feed](./figs/feed_result.png) ## 3. 如何解决问题 diff --git a/example/peripheral/wdt/configs/d2000_aarch32_test_wdt.config b/example/peripheral/wdt/configs/d2000_aarch32_test_wdt.config index aae08e3356608bcf184d1656f2096ee24b76cf4a..9595c92e6c72fd8452f3a2927b0cb9b8edc395b0 100644 --- a/example/peripheral/wdt/configs/d2000_aarch32_test_wdt.config +++ b/example/peripheral/wdt/configs/d2000_aarch32_test_wdt.config @@ -59,7 +59,6 @@ CONFIG_F32BIT_MEMORY_ADDRESS=0x80000000 CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -88,9 +87,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/configs/d2000_aarch64_test_wdt.config b/example/peripheral/wdt/configs/d2000_aarch64_test_wdt.config index b1f6b4e44ec24c8dcb1a22be2186d681798410f6..e995b501ab41ba71c1456bba34f29ca4da62b8b5 100644 --- a/example/peripheral/wdt/configs/d2000_aarch64_test_wdt.config +++ b/example/peripheral/wdt/configs/d2000_aarch64_test_wdt.config @@ -53,7 +53,6 @@ CONFIG_F32BIT_MEMORY_ADDRESS=0x80000000 CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -82,9 +81,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/configs/e2000d_aarch32_demo_wdt.config b/example/peripheral/wdt/configs/e2000d_aarch32_demo_wdt.config index 08a58b0a2fc5d4d482092bfbc1c85cdeaa4d6c32..06135ee2c2fe57e4ce545632fee059f9ca0a6a52 100644 --- a/example/peripheral/wdt/configs/e2000d_aarch32_demo_wdt.config +++ b/example/peripheral/wdt/configs/e2000d_aarch32_demo_wdt.config @@ -60,7 +60,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -101,9 +100,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/configs/e2000d_aarch64_demo_wdt.config b/example/peripheral/wdt/configs/e2000d_aarch64_demo_wdt.config index 320fe8d9076568dc135d05e30fa6312d84711777..d94c7a76e449caf2a95fb7cc732426e4fa409ff6 100644 --- a/example/peripheral/wdt/configs/e2000d_aarch64_demo_wdt.config +++ b/example/peripheral/wdt/configs/e2000d_aarch64_demo_wdt.config @@ -54,7 +54,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -95,9 +94,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/configs/e2000q_aarch32_demo_wdt.config b/example/peripheral/wdt/configs/e2000q_aarch32_demo_wdt.config index 4664cf8f36cdc619ac5476c9941805542972c9dc..c9c9a32d3d01842fda32e63557ff8ca9b10490ce 100644 --- a/example/peripheral/wdt/configs/e2000q_aarch32_demo_wdt.config +++ b/example/peripheral/wdt/configs/e2000q_aarch32_demo_wdt.config @@ -60,7 +60,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -100,9 +99,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/configs/e2000q_aarch64_demo_wdt.config b/example/peripheral/wdt/configs/e2000q_aarch64_demo_wdt.config index 2ae3baa4f28e59ea3bc9f7adc17e6e119266c7a5..e8c2d1bea5cabe2ce9d5f05adef3840c01ad8553 100644 --- a/example/peripheral/wdt/configs/e2000q_aarch64_demo_wdt.config +++ b/example/peripheral/wdt/configs/e2000q_aarch64_demo_wdt.config @@ -54,7 +54,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -94,9 +93,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/configs/ft2004_aarch32_dsk_wdt.config b/example/peripheral/wdt/configs/ft2004_aarch32_dsk_wdt.config index 4fefcbb6860f2e93db6cbecf71fe0d617548cf94..1ea007c0452d510275d1155208a3df90e2c0cb82 100644 --- a/example/peripheral/wdt/configs/ft2004_aarch32_dsk_wdt.config +++ b/example/peripheral/wdt/configs/ft2004_aarch32_dsk_wdt.config @@ -59,7 +59,6 @@ CONFIG_F32BIT_MEMORY_ADDRESS=0x80000000 CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -88,9 +87,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/configs/ft2004_aarch64_dsk_wdt.config b/example/peripheral/wdt/configs/ft2004_aarch64_dsk_wdt.config index af9b764e7db53769237684486c5c8e3f04d2bf28..51a301dc93f2f3c8864ed4c54052fbd0c99dfab7 100644 --- a/example/peripheral/wdt/configs/ft2004_aarch64_dsk_wdt.config +++ b/example/peripheral/wdt/configs/ft2004_aarch64_dsk_wdt.config @@ -53,7 +53,6 @@ CONFIG_F32BIT_MEMORY_ADDRESS=0x80000000 CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -82,9 +81,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/configs/phytiumpi_aarch32_firefly_wdt.config b/example/peripheral/wdt/configs/phytiumpi_aarch32_firefly_wdt.config index 14155a30a053b4f22783f4f6b754fb30db94441a..e7a274633e2fa6fa993d0263ea4242f5d0c7ab80 100644 --- a/example/peripheral/wdt/configs/phytiumpi_aarch32_firefly_wdt.config +++ b/example/peripheral/wdt/configs/phytiumpi_aarch32_firefly_wdt.config @@ -59,7 +59,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -99,9 +98,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/configs/phytiumpi_aarch64_firefly_wdt.config b/example/peripheral/wdt/configs/phytiumpi_aarch64_firefly_wdt.config index 3b36f05a555daba982fd32021ce82e2dace4cadb..279f43b43292ffa4ac3b60d7d3a64fc8156a0298 100644 --- a/example/peripheral/wdt/configs/phytiumpi_aarch64_firefly_wdt.config +++ b/example/peripheral/wdt/configs/phytiumpi_aarch64_firefly_wdt.config @@ -53,7 +53,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -93,9 +92,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/figs/create.png b/example/peripheral/wdt/figs/create.png deleted file mode 100644 index 1b79c0cd681cd33bd3498791025a4aa5bb66739f..0000000000000000000000000000000000000000 Binary files a/example/peripheral/wdt/figs/create.png and /dev/null differ diff --git a/example/peripheral/wdt/figs/delete.png b/example/peripheral/wdt/figs/delete.png deleted file mode 100644 index 8c33a8d44bab354c82752c5c100ef29f175a57aa..0000000000000000000000000000000000000000 Binary files a/example/peripheral/wdt/figs/delete.png and /dev/null differ diff --git a/example/peripheral/wdt/figs/feed_result.png b/example/peripheral/wdt/figs/feed_result.png new file mode 100644 index 0000000000000000000000000000000000000000..6bd2d33f78b57e29e762dc6144c4081564ec7e63 Binary files /dev/null and b/example/peripheral/wdt/figs/feed_result.png differ diff --git a/example/peripheral/wdt/inc/wdt_example.h b/example/peripheral/wdt/inc/wdt_example.h index ed1e77baa124dead93095e53be5379e15e075e26..d999b014eb24ed6233ab52a7271c161e635de71b 100644 --- a/example/peripheral/wdt/inc/wdt_example.h +++ b/example/peripheral/wdt/inc/wdt_example.h @@ -20,6 +20,7 @@ * Ver    Who          Date          Changes * -----  ------      --------     -------------------------------------- * 1.0 wangxiaodong 2022/8/9 first release + * 2.0 liqiaozhong 2024/4/22 add no letter shell mode, adapt to auto-test system */ @@ -31,8 +32,8 @@ extern "C" { #endif -/* wdt read and write test */ -BaseType_t FFreeRTOSWdtCreate(u32 id); +/* wdt feed test */ +int FFreeRTOSWdtCreate(void); #ifdef __cplusplus } diff --git a/example/peripheral/wdt/main.c b/example/peripheral/wdt/main.c index 2dd2538b27aca08aad3226ec1171815cdecd0cf7..181cf17b120fe33c3678cabf9498ba97ada84a50 100644 --- a/example/peripheral/wdt/main.c +++ b/example/peripheral/wdt/main.c @@ -20,33 +20,63 @@ * Ver    Who          Date          Changes * -----  ------      --------     -------------------------------------- * 1.0 wangxiaodong 2022/8/9 first release + * 2.0 liqiaozhong 2024/4/22 add no letter shell mode, adapt to auto-test system */ -#include "shell.h" -#include "shell_port.h" #include + +#include "FreeRTOS.h" +#include "task.h" + +#include "sdkconfig.h" + #include "wdt_example.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "shell.h" +#include "shell_port.h" +#endif + +#define WDT_EXAMPLE_TASK_PRIORITY 2 + +void WdtExampleTaskEntry() +{ + /* example functions */ + FFreeRTOSWdtCreate(); + + /* end flag */ + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} + int main(void) { - BaseType_t ret; + BaseType_t ret = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ - ret = FFreeRTOSWdtCreate(0); + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)WdtExampleTaskEntry, /* 任务入口函数 */ + (const char *)"WdtExampleTaskEntry", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)WDT_EXAMPLE_TASK_PRIORITY, /* 任务优先级 */ + NULL); if (ret != pdPASS) { goto FAIL_EXIT; } - ret = LSUserShellTask() ; +#ifdef CONFIG_USE_LETTER_SHELL + ret = LSUserShellTask(); if (ret != pdPASS) { goto FAIL_EXIT; } +#endif vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("Failed,the ret value is 0x%x. \r\n", ret); - return 0; -} + printf("WDT example failed in main.c, the ret value is 0x%x. \r\n", ret); + return -2; +} \ No newline at end of file diff --git a/example/peripheral/wdt/makefile b/example/peripheral/wdt/makefile index 13c14898d0f8ad5159f3e5baa6067deda58349eb..8cdbb131737371bf472dd0695f73ceba32b2c1a4 100644 --- a/example/peripheral/wdt/makefile +++ b/example/peripheral/wdt/makefile @@ -8,7 +8,6 @@ BOOT_IMG_NAME ?= freertos USER_CSRC := main.c USER_CSRC += $(wildcard src/*.c) -USER_CSRC += $(wildcard ../common/*.c) USER_ASRC := USER_CXXSRC := diff --git a/example/peripheral/wdt/sdkconfig b/example/peripheral/wdt/sdkconfig index 3b36f05a555daba982fd32021ce82e2dace4cadb..279f43b43292ffa4ac3b60d7d3a64fc8156a0298 100644 --- a/example/peripheral/wdt/sdkconfig +++ b/example/peripheral/wdt/sdkconfig @@ -53,7 +53,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -93,9 +92,9 @@ CONFIG_TARGET_NAME="wdt" # # CONFIG_LOG_VERBOS is not set # CONFIG_LOG_DEBUG is not set -CONFIG_LOG_INFO=y +# CONFIG_LOG_INFO is not set # CONFIG_LOG_WARN is not set -# CONFIG_LOG_ERROR is not set +CONFIG_LOG_ERROR=y # CONFIG_LOG_NONE is not set # CONFIG_LOG_EXTRA_INFO is not set # CONFIG_LOG_DISPALY_CORE_NUM is not set diff --git a/example/peripheral/wdt/sdkconfig.h b/example/peripheral/wdt/sdkconfig.h index 44ff5f90c6f362741f46835588de432132ab19fd..2d46a73e41bac4eab8c926cb84c46e3bc4a06721 100644 --- a/example/peripheral/wdt/sdkconfig.h +++ b/example/peripheral/wdt/sdkconfig.h @@ -51,7 +51,6 @@ #define CONFIG_F64BIT_MEMORY_ADDRESS 0x2000000000 #define CONFIG_F64BIT_MEMORY_LENGTH 0x800000000 #define CONFIG_TARGET_E2000 -/* CONFIG_USE_SPINLOCK is not set */ #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 /* CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set */ /* CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set */ @@ -86,9 +85,9 @@ /* CONFIG_LOG_VERBOS is not set */ /* CONFIG_LOG_DEBUG is not set */ -#define CONFIG_LOG_INFO +/* CONFIG_LOG_INFO is not set */ /* CONFIG_LOG_WARN is not set */ -/* CONFIG_LOG_ERROR is not set */ +#define CONFIG_LOG_ERROR /* CONFIG_LOG_NONE is not set */ /* CONFIG_LOG_EXTRA_INFO is not set */ /* CONFIG_LOG_DISPALY_CORE_NUM is not set */ diff --git a/example/peripheral/wdt/src/wdt_example.c b/example/peripheral/wdt/src/wdt_example.c index 0293d8ac544d97f6a76fb412bccdfe4a248faa65..167d1bb226416194b5a0cdfcf7f7487cc5fbf2ff 100644 --- a/example/peripheral/wdt/src/wdt_example.c +++ b/example/peripheral/wdt/src/wdt_example.c @@ -20,307 +20,229 @@ * Ver    Who          Date          Changes * -----  ------      --------     -------------------------------------- * 1.0 wangxiaodong 2022/8/9 first release + * 2.0 liqiaozhong 2024/4/22 add no letter shell mode, adapt to auto-test system */ + #include + #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" #include "queue.h" -#include "timers.h" + #include "fparameters.h" #include "fgeneric_timer.h" -#include "fwdt.h" +#include "fdebug.h" + #include "fwdt_os.h" #include "fcpu_info.h" -#include "wdt_example.h" - -/* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 15000UL ) ) -#define AUTO_RELOAD_TIMER_PERIOD ( pdMS_TO_TICKS( 1000UL ) ) - -/* watchdog timeout value in seconds */ -#define WDT_TIMEOUT 4 - -/* watchdog feed period */ -#define WDT_FEED_PERIOD ( pdMS_TO_TICKS( 3000UL )) - -/* test task number */ -#define READ_WRITE_TASK_NUM 2 -static xSemaphoreHandle xCountingSemaphore; - -static xTaskHandle queue_receive_handle; -static xTaskHandle feed_handle; -static TimerHandle_t xOneShotTimer; -static TimerHandle_t xAutoReloadTimer; -/* Declare a variable of type QueueHandle_t. This is used to store the queue -that is accessed by all three tasks. */ -static QueueHandle_t xQueue; - -static FFreeRTOSWdt *os_wdt_ctrl_p; - -typedef struct +#define FWDT_DEBUG_TAG "WDT-EXAMPLE" +#define FWDT_ERROR(format, ...) FT_DEBUG_PRINT_E(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) +#define FWDT_WARN(format, ...) FT_DEBUG_PRINT_W(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) +#define FWDT_INFO(format, ...) FT_DEBUG_PRINT_I(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) +#define FWDT_DEBUG(format, ...) FT_DEBUG_PRINT_D(FWDT_DEBUG_TAG, format, ##__VA_ARGS__) + +/* user-define */ +#define WDT_CONTROLLER_ID FWDT0_ID +#define WDT_FEED_TIMES 3 /* 喂狗操作次数 */ +#define WDT_ONCE_TIMEOUT 3 /* watchdog timeout value in seconds */ +#define WDT_FEED_PERIOD (pdMS_TO_TICKS(15000UL)) /* 喂狗操作最长执行时间,设置时需要考虑WDT_FEED_TIMES与WDT_ONCE_TIMEOUT */ +#define WDT_FEED_TASK_PRIORITY 3 +#define WDT_EXAMPLE_TIMEOUT (WDT_FEED_PERIOD + (pdMS_TO_TICKS(3000UL))) /* 用例最长执行时间 */ + +enum { - u32 count; - FWdtCtrl *ctrl; -} FWdtQueueData; + WDT_EXAMPLE_SUCCESS = 0, + WDT_EXAMPLE_UNKNOWN_STATE, + WDT_EXAMPLE_INIT_FAILURE, + WDT_EXAMPLE_FEED_FAILURE, +}; -static void FFreeRTOSWdtDelete(FFreeRTOSWdt *os_wdt_p); +static FFreeRTOSWdt *os_wdt_ctrl_p; +static u32 wdt_feed_count = 0; /* 记录喂狗次数 */ +static QueueHandle_t xQueue = NULL; +static TaskHandle_t wdt_feed_task = NULL; +const UBaseType_t wdt_feed_task_index = 0; /* the index must set to 0 */ static void FFreeRTOSWdtInterruptHandler(s32 vector, void *param) { FASSERT(param != NULL); - static FWdtQueueData xSendStructure; - - portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; - - xSendStructure.ctrl = (FWdtCtrl *)param; - xSendStructure.count++; - - FWdtRefresh(xSendStructure.ctrl); - - printf("FFreeRTOSWdtInterruptHandler has been run %d times \r\n", xSendStructure.count); - - xQueueSendToBackFromISR(xQueue, &xSendStructure, &xHigherPriorityTaskWoken); - - /* never call taskYIELD() form ISR! */ - portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); + FWdtCtrl *wdt_ctrl_p_irq = (FWdtCtrl *)param; + BaseType_t xhigher_priority_task_woken = pdFALSE; + u32 second = 0; + if (wdt_feed_count >= WDT_FEED_TIMES) + { + FWdtRefresh(wdt_ctrl_p_irq); + vTaskNotifyGiveIndexedFromISR(wdt_feed_task, wdt_feed_task_index, &xhigher_priority_task_woken); + printf("Receive WDT timeout intr and try to return.\r\n"); + portYIELD_FROM_ISR(xhigher_priority_task_woken); /* 如果中断触发了更高优先级的任务,确保更高优先级的任务尽快执行 */ + } + else + { + FWdtRefresh(wdt_ctrl_p_irq); + second = GenericTimerRead(GENERIC_TIMER_ID0) / GenericTimerFrequecy(); + printf("Receive WDT timeout intr and refresh it, count: %d, second: %d\r\n", wdt_feed_count, second); + wdt_feed_count ++; + } } -static void FFreeRTOSWdtInitTask(void *pvParameters) +static FError WdtExampleInit(void) { - /* The wdt_id to use is passed in via the parameter. - Cast this to a wdt_id pointer. */ - u32 wdt_id = (u32)(uintptr)pvParameters; - u32 timeout = WDT_TIMEOUT; - u32 cpu_id = 0; - + FError ret = FWDT_SUCCESS; + /* init wdt controller */ - os_wdt_ctrl_p = FFreeRTOSWdtInit(wdt_id); + os_wdt_ctrl_p = FFreeRTOSWdtInit(WDT_CONTROLLER_ID); if (os_wdt_ctrl_p == NULL) { - printf("FFreeRTOSWdtInit failed.\n"); + ret = FREERTOS_WDT_INIT_ERROR; + FWDT_ERROR("FFreeRTOSWdtInit() error."); goto wdt_init_exit; } - /* set wdt timeout value */ - FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_SET_TIMEOUT, &timeout); - - /* start wdt controller */ - FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_START, NULL); /* set wdt timeout interrupt handler */ + u32 cpu_id = 0; FWdtCtrl *pctrl = &os_wdt_ctrl_p->wdt_ctrl; FWdtConfig *pconfig = &os_wdt_ctrl_p->wdt_ctrl.config; GetCpuId(&cpu_id); + printf("WDT_CONTROLLER_ID: %d, pconfig->irq_num: %ld\r\n", WDT_CONTROLLER_ID, pconfig->irq_num); InterruptSetTargetCpus(pconfig->irq_num, cpu_id); + /* interrupt init */ InterruptSetPriority(pconfig->irq_num, pconfig->irq_prority); InterruptInstall(pconfig->irq_num, FFreeRTOSWdtInterruptHandler, pctrl, pconfig->instance_name); InterruptUmask(pconfig->irq_num); - printf("FFreeRTOSWdtInitTask execute successfully.\r\n"); - - for (int i = 0; i < READ_WRITE_TASK_NUM; i++) - { - xSemaphoreGive(xCountingSemaphore); - } - wdt_init_exit: - vTaskDelete(NULL); + FWDT_INFO("%s return with ret: %d", __func__, ret); + return ret; } -static void FFreeRTOSWdtQueueReceiveTask(void) +static FError WdtExampleFeed(void) { - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - static FWdtQueueData xReceiveStructure; + FError ret = FWDT_SUCCESS; + uint32_t notify_result; + u32 wdt_timeout = WDT_ONCE_TIMEOUT; /* 为了传入地址,重新赋值 */ + const TickType_t max_block_time = WDT_FEED_PERIOD; - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) + /* set wdt timeout value */ + ret = FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_SET_TIMEOUT, &wdt_timeout); + if (ret != FWDT_SUCCESS) { - xQueueReceive(xQueue, &xReceiveStructure, portMAX_DELAY); - u32 seconds = GenericTimerRead(GENERIC_TIMER_ID0) / GenericTimerFrequecy(); - vPrintf("FFreeRTOSWdtQueueReceiveTask run, count = %d, time seconds: %d\r\n", xReceiveStructure.count, seconds); + FWDT_ERROR("FFreeRTOSWdtControl SET_TIMEOUT error."); + goto wdt_feed_exit; } -} -static void FFreeRTOSWdtFeedTask(void *pvParameters) -{ - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); + wdt_feed_task = xTaskGetCurrentTaskHandle(); - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) + /* start wdt controller */ + ret = FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_START, NULL); + if (ret != FWDT_SUCCESS) { - FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_KEEPALIVE, NULL); - u32 seconds = GenericTimerRead(GENERIC_TIMER_ID0) / GenericTimerFrequecy(); - vPrintf("FFreeRTOSWdtFeedTask run, time seconds: %d\r\n", seconds); - vTaskDelay(WDT_FEED_PERIOD); + FWDT_ERROR("FFreeRTOSWdtControl CTRL_START error."); + goto wdt_feed_exit; } -} - -static void prvOneShotTimerCallback(TimerHandle_t xTimer) -{ - /* Output a string to show the time at which the callback was executed. */ - vPrintf("One-shot timer callback executing, will delete FFreeRTOSWdtFeedTask.\r\n"); - - /* The count of the number of times this software timer has expired is - stored in the timer's ID. Obtain the ID, increment it, then save it as the - new ID value. The ID is a void pointer, so is cast to a uint32_t. */ - if (feed_handle) + notify_result = ulTaskNotifyTakeIndexed(wdt_feed_task_index, pdTRUE, max_block_time); /* 等待喂狗完毕后产生的超时中断 */ + if (notify_result != 1) { - vTaskDelete(feed_handle); - vPrintf("Delete FFreeRTOSWdtFeedTask success.\r\n"); + ret = FREERTOS_WDT_SEM_ERROR; + FWDT_ERROR("Wait WDT finish notify_result timeout."); + goto wdt_feed_exit; } -} - -static void prvAutoReloadTimerCallback(TimerHandle_t xTimer) -{ - /* Output a string to show the time at which the callback was executed. */ - static u32 count = 0; - u32 time_left = 0; - - count++; - /* The count of the number of times this software timer has expired is - stored in the timer's ID. Obtain the ID, increment it, then save it as the - new ID value. The ID is a void pointer, so is cast to a uint32_t. */ - - if (count >= 30) + ret = FFreeRTOSWdtControl(os_wdt_ctrl_p, FREERTOS_WDT_CTRL_STOP, NULL); + if (ret != FWDT_SUCCESS) { - vPrintf("Auto-reload callback executing, Delete FFreeRTOSWdtQueueReceiveTask and software timer.\r\n"); - FFreeRTOSWdtDelete(os_wdt_ctrl_p); + FWDT_ERROR("FFreeRTOSWdtControl CTRL_STOP error."); + goto wdt_feed_exit; } + + +wdt_feed_exit: + FWDT_INFO("%s return with ret: %d", __func__, ret); + return ret; } -BaseType_t FFreeRTOSWdtCreate(u32 id) +static void WdtExampleTask() { - BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - BaseType_t xTimer1Started = pdPASS; - BaseType_t xTimer2Started = pdPASS; - u32 wdt_id = id; - /* The queue is created to hold a maximum of 3 structures of type xData. */ - xQueue = xQueueCreate(3, sizeof(FWdtQueueData)); - if (xQueue == NULL) - { - printf("FFreeRTOSWdtCreate FWdtQueueData create failed.\r\n"); - return pdFAIL; - } + FError ret = FWDT_SUCCESS; + int task_res = WDT_EXAMPLE_SUCCESS; - xCountingSemaphore = xSemaphoreCreateCounting(READ_WRITE_TASK_NUM, 0); - if (xCountingSemaphore == NULL) + ret = WdtExampleInit(); + if (ret != FWDT_SUCCESS) { - printf("FFreeRTOSWdtCreate xCountingSemaphore create failed.\r\n"); - return pdFAIL; + task_res = WDT_EXAMPLE_INIT_FAILURE; + FWDT_ERROR("WdtExampleInit() failed."); + goto task_exit; } - taskENTER_CRITICAL(); //进入临界区 - /* wdt init task */ - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSWdtInitTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSWdtInitTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - (void *)(uintptr)id,/* 任务入口函数参数 */ - (UBaseType_t)1, /* 任务的优先级 */ - NULL); /* 任务控制 */ - - /* 看门狗后半段的处理任务,等待处理超时中断触发后的发送的消息队列 */ - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSWdtQueueReceiveTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSWdtQueueReceiveTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ - (TaskHandle_t *)&queue_receive_handle); /* 任务控制 */ - - /* 主动喂狗任务,周期比看门狗的超时时间短 */ - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSWdtFeedTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSWdtFeedTask",/* 任务名字 */ - (uint16_t)1024, /* 任务栈大小 */ - NULL,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ - (TaskHandle_t *)&feed_handle); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate("OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example use the timer id. */ - prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ - - /* Create the auto-reload, storing the handle to the created timer in - xAutoReloadTimer. */ - xAutoReloadTimer = xTimerCreate("Auto-reload Timer", /* Text name for the software timer - not used by FreeRTOS. */ - AUTO_RELOAD_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdTRUE, /* Set uxAutoRealod to pdTRUE to create an auto-reload timer. */ - 0, /* This example use the timer id. */ - prvAutoReloadTimerCallback); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if ((xOneShotTimer != NULL) && (xAutoReloadTimer != NULL)) + ret = WdtExampleFeed(); /* 尝试喂几次狗,如果没有出现系统自动复位的现象,则说明喂狗成功,最后等待超时中断产生后退出 */ + if (ret != FWDT_SUCCESS) { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimer1Started = xTimerStart(xOneShotTimer, 0); - xTimer2Started = xTimerStart(xAutoReloadTimer, 0); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if ((xTimer1Started != pdPASS) || (xTimer2Started != pdPASS)) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed.\r\n"); - } + task_res = WDT_EXAMPLE_FEED_FAILURE; + FWDT_ERROR("WdtExampleFeed() failed."); + goto task_exit; } - else + +task_exit: + if (os_wdt_ctrl_p != NULL) { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed.\r\n"); + FFreeRTOSWdtDeinit(os_wdt_ctrl_p); } - taskEXIT_CRITICAL(); //退出临界区 + xQueueSend(xQueue, &task_res, 0); - return xReturn; + vTaskDelete(NULL); } -static void FFreeRTOSWdtDelete(FFreeRTOSWdt *os_wdt_p) + +int FFreeRTOSWdtCreate(void) { - BaseType_t xReturn = pdPASS; - FFreeRTOSWdtControl(os_wdt_p, FREERTOS_WDT_CTRL_STOP, NULL); - FFreeRTOSWdtDeinit(os_wdt_p); - if (queue_receive_handle) + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = WDT_EXAMPLE_UNKNOWN_STATE; + + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) { - vTaskDelete(queue_receive_handle); - vPrintf("Delete FFreeRTOSWdtQueueReceiveTask success.\r\n"); + FWDT_ERROR("xQueue create failed."); + goto exit; } - /* delete queue */ - vQueueDelete(xQueue); - - /* delete count sem */ - vSemaphoreDelete(xCountingSemaphore); + xReturn = xTaskCreate((TaskFunction_t)WdtExampleTask, /* 任务入口函数 */ + (const char *)"WdtExampleTask", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)WDT_FEED_TASK_PRIORITY, /* 任务优先级 */ + NULL); /* 任务句柄 */ + if (xReturn == pdFAIL) + { + FWDT_ERROR("xTaskCreate WdtExampleTask failed."); + goto exit; + } - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if (xReturn != pdPASS) + xReturn = xQueueReceive(xQueue, &task_res, WDT_EXAMPLE_TIMEOUT); + if (xReturn == pdFAIL) { - vPrintf("Delete OneShot Software Timer failed.\r\n"); + FWDT_ERROR("xQueue receive timeout."); + goto exit; } - else + +exit: + if (xQueue != NULL) { - vPrintf("Delete OneShot Software Timer success.\r\n"); + vQueueDelete(xQueue); } - xReturn = xTimerDelete(xAutoReloadTimer, 0); - if (xReturn != pdPASS) + if (task_res != WDT_EXAMPLE_SUCCESS) { - vPrintf("Delete AutoReload Software Timer failed.\r\n"); + printf("%s@%d: WDT feed example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return task_res; } else { - vPrintf("Delete AutoReload Software Timer success.\r\n"); + printf("%s@%d: WDT feed example [success].\r\n", __func__, __LINE__); + return task_res; } } \ No newline at end of file diff --git a/example/storage/fatfs/README.md b/example/storage/fatfs/README.md index 03d347d5eb480c8f1e057207e92d9552c16ae4a0..8fd212270271320af660439a11ce89846285d5fb 100644 --- a/example/storage/fatfs/README.md +++ b/example/storage/fatfs/README.md @@ -10,7 +10,7 @@ 本例程需要用到 - Phytium开发板(E2000D/E2000Q/PhytiumPi) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ![hardware](./figures/hardware.png) @@ -75,27 +75,32 @@ bootelf -p 0x90100000 ### 2.4 输出与实验现象 - 打开配置 CONFIG_FATFS_SDIF_TF, 使能 MicroSD(TF) 卡 +> 注意如果不需要使用分区功能请将CONFIG_FATFS_SDMMC_PARTITION设置为0,如果需要使用分区功能则请确保在MicroSD(TF)卡中已做好分区操作 - 打开配置 CONFIG_FATFS_SDIF_EMMC, 使能 eMMC - 打开配置 CONFIG_FATFS_USB, 使能 U 盘 - 打开配置 CONFIG_FATFS_FSATA, 使能 SATA 硬盘 - 打开配置 CONFIG_FATFS_FSATA_PCIE, 使能 SATA 硬盘与 PCIE 接口 +> 请确保存储设备已连接到开发板再打开对应配置,否则程序可能会死循环 + +![](./figures/config.png) - 打开配置 CONFIG_FATFS_BASIC_TEST,测试 FATFS 的基本功能 - 打开配置 CONFIG_FATFS_SPEED_TEST, 测试 FATFS 的读写速度,会破环文件系统 - 打开配置 CONFIG_FATFS_CYCLE_TEST, 运行 FATFS 的测试项,会破环文件系统 -- 编译镜像,加载到开发板上电启动 - -![](./figures/config.png) - ![](./figures/test_item.png) -- 加载镜像启动后,自动开始测试 +- 编译镜像,加载到开发板上电启动 + +> shell中输入命令 fatfs test,启动测试。 ![](./figures/test_1.png) ![](./figures/test_2.png) ![](./figures/test_3.png) ![](./figures/test_4.png) -![](./figures/test_5.png) ## 3. 如何解决问题 - \ No newline at end of file + +1. fatfs_example.c中定义了WAIT_TIMEOUT变量,决定Task最长阻塞时间。如果测试时间过长,超过了WAIT_TIMEOUT, 那么程序会报告failure。可选择增大WAIT_TIMEOUT或减少测试时读写的字节数解决这一问题。 + +2. 关闭CONFIG_FATFS_USB配置的同时,需要关闭Use CherryUSB,否则编译会报错。 + diff --git a/example/storage/fatfs/configs/e2000d_aarch32_demo_fatfs.config b/example/storage/fatfs/configs/e2000d_aarch32_demo_fatfs.config index d8f2b90a34011ced30aaaf6ab1d56b084c758caf..86676f2d9248dfec971cc8c2cccf641b4e792fcf 100644 --- a/example/storage/fatfs/configs/e2000d_aarch32_demo_fatfs.config +++ b/example/storage/fatfs/configs/e2000d_aarch32_demo_fatfs.config @@ -3,8 +3,8 @@ # Project Configuration # CONFIG_FATFS_BASIC_TEST=y -# CONFIG_FATFS_SPEED_TEST is not set -# CONFIG_FATFS_CYCLE_TEST is not set +CONFIG_FATFS_SPEED_TEST=y +CONFIG_FATFS_CYCLE_TEST=y # end of Project Configuration CONFIG_USE_FREERTOS=y @@ -69,7 +69,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set diff --git a/example/storage/fatfs/configs/e2000d_aarch64_demo_fatfs.config b/example/storage/fatfs/configs/e2000d_aarch64_demo_fatfs.config index 1d55ab33f94b81d910e8545c39d797bccfff3837..440d2ea36dfe445f3f63cdbc4b6204d41203028b 100644 --- a/example/storage/fatfs/configs/e2000d_aarch64_demo_fatfs.config +++ b/example/storage/fatfs/configs/e2000d_aarch64_demo_fatfs.config @@ -3,8 +3,8 @@ # Project Configuration # CONFIG_FATFS_BASIC_TEST=y -# CONFIG_FATFS_SPEED_TEST is not set -# CONFIG_FATFS_CYCLE_TEST is not set +CONFIG_FATFS_SPEED_TEST=y +CONFIG_FATFS_CYCLE_TEST=y # end of Project Configuration CONFIG_USE_FREERTOS=y @@ -40,7 +40,7 @@ CONFIG_GCC_CODE_MODEL_SMALL=y CONFIG_USE_CACHE=y CONFIG_USE_MMU=y -# CONFIG_BOOT_WITH_FLUSH_CACHE is not set +CONFIG_BOOT_WITH_FLUSH_CACHE=y # CONFIG_MMU_DEBUG_PRINTS is not set # end of Arm architecture configuration # end of Arch configuration @@ -63,7 +63,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set diff --git a/example/storage/fatfs/configs/e2000q_aarch32_demo_fatfs.config b/example/storage/fatfs/configs/e2000q_aarch32_demo_fatfs.config index ec02662a638636cdd1fe804593902ddee9edb71a..c5f5d2e3d6e45e332f6b38ffc0bd035912bcf4f2 100644 --- a/example/storage/fatfs/configs/e2000q_aarch32_demo_fatfs.config +++ b/example/storage/fatfs/configs/e2000q_aarch32_demo_fatfs.config @@ -3,8 +3,8 @@ # Project Configuration # CONFIG_FATFS_BASIC_TEST=y -# CONFIG_FATFS_SPEED_TEST is not set -# CONFIG_FATFS_CYCLE_TEST is not set +CONFIG_FATFS_SPEED_TEST=y +CONFIG_FATFS_CYCLE_TEST=y # end of Project Configuration CONFIG_USE_FREERTOS=y @@ -69,7 +69,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set diff --git a/example/storage/fatfs/configs/e2000q_aarch64_demo_fatfs.config b/example/storage/fatfs/configs/e2000q_aarch64_demo_fatfs.config index 3534b6d2b161ec71977af5d166d020a1029d69f1..8328126b5854f109b418a40093fa9eaeb9b57708 100644 --- a/example/storage/fatfs/configs/e2000q_aarch64_demo_fatfs.config +++ b/example/storage/fatfs/configs/e2000q_aarch64_demo_fatfs.config @@ -3,8 +3,8 @@ # Project Configuration # CONFIG_FATFS_BASIC_TEST=y -# CONFIG_FATFS_SPEED_TEST is not set -# CONFIG_FATFS_CYCLE_TEST is not set +CONFIG_FATFS_SPEED_TEST=y +CONFIG_FATFS_CYCLE_TEST=y # end of Project Configuration CONFIG_USE_FREERTOS=y @@ -40,7 +40,7 @@ CONFIG_GCC_CODE_MODEL_SMALL=y CONFIG_USE_CACHE=y CONFIG_USE_MMU=y -# CONFIG_BOOT_WITH_FLUSH_CACHE is not set +CONFIG_BOOT_WITH_FLUSH_CACHE=y # CONFIG_MMU_DEBUG_PRINTS is not set # end of Arm architecture configuration # end of Arch configuration @@ -63,7 +63,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -213,7 +212,7 @@ CONFIG_DEFAULT_LINKER_SCRIPT=y CONFIG_IMAGE_LOAD_ADDRESS=0x80100000 CONFIG_IMAGE_MAX_LENGTH=0x2000000 CONFIG_HEAP_SIZE=2 -CONFIG_STACK_SIZE=0x100000 +CONFIG_STACK_SIZE=0x400 # end of Linker Options # end of Build setup diff --git a/example/storage/fatfs/configs/phytiumpi_aarch32_firefly_fatfs.config b/example/storage/fatfs/configs/phytiumpi_aarch32_firefly_fatfs.config index 03a2649f4711051f829cf7c3029297d1a46b7619..bd843c9d90f3634359d075830c51221990de9490 100644 --- a/example/storage/fatfs/configs/phytiumpi_aarch32_firefly_fatfs.config +++ b/example/storage/fatfs/configs/phytiumpi_aarch32_firefly_fatfs.config @@ -3,8 +3,8 @@ # Project Configuration # CONFIG_FATFS_BASIC_TEST=y -# CONFIG_FATFS_SPEED_TEST is not set -# CONFIG_FATFS_CYCLE_TEST is not set +CONFIG_FATFS_SPEED_TEST=y +CONFIG_FATFS_CYCLE_TEST=y # end of Project Configuration CONFIG_USE_FREERTOS=y @@ -68,7 +68,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -358,21 +357,11 @@ CONFIG_FATFS_RAM_DISK_SIZE_MB=500 CONFIG_FATFS_RAM_DISK_SECTOR_SIZE_BYTE=512 # end of RAM Disk Configuration -CONFIG_FATFS_SDMMC=y -CONFIG_FATFS_SDMMC_FSDIF_TF=y -CONFIG_FATFS_SDMMC_FSDIF_EMMC=y -CONFIG_FATFS_SDMMC_PARTITION=1 +# CONFIG_FATFS_SDMMC_FSDIF_TF is not set +# CONFIG_FATFS_SDMMC_FSDIF_EMMC is not set # CONFIG_FATFS_SDMMC_FSDMMC_TF is not set -CONFIG_FATFS_SATA_DISK=y - -# -# SATA Disk Configuration -# -# CONFIG_FATFS_FSATA is not set -# CONFIG_FATFS_FSATA_PCIE is not set -# end of SATA Disk Configuration - -CONFIG_FATFS_USB=y +# CONFIG_FATFS_SATA_DISK is not set +# CONFIG_FATFS_USB is not set CONFIG_FATFS_VOLUME_COUNT=10 # CONFIG_FATFS_LFN_NONE is not set CONFIG_FATFS_LFN_HEAP=y @@ -390,23 +379,7 @@ CONFIG_USE_TLSF=y # CONFIG_USE_LITTLE_FS is not set # CONFIG_USE_LVGL is not set # CONFIG_USE_FREEMODBUS is not set -CONFIG_USE_CHERRY_USB=y - -# -# CherryUSB Configuration -# -CONFIG_CHERRY_USB_PORT_XHCI=y -# CONFIG_CHERRY_USB_PORT_PHYTIUM_OTG is not set -CONFIG_CHERRYUSB_HOST=y -# CONFIG_CHERRYUSB_DEVICE is not set -CONFIG_CHERRY_USB_HOST_HUB=y -CONFIG_CHERRY_USB_HOST_MSC=y -# CONFIG_CHERRY_USB_HOST_HID is not set -# CONFIG_CHERRY_USB_HOST_VEDIO is not set -# CONFIG_CHERRY_USB_HOST_CDC is not set -# CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS is not set -# end of CherryUSB Configuration - +# CONFIG_USE_CHERRY_USB is not set CONFIG_USE_FSL_SDMMC=y # diff --git a/example/storage/fatfs/configs/phytiumpi_aarch64_firefly_fatfs.config b/example/storage/fatfs/configs/phytiumpi_aarch64_firefly_fatfs.config index dd87b0e5d944415e8e1d1f97ca9a8333f81bf34b..adcd5447d59c9d3d6618f7bd0bebecff250de30f 100644 --- a/example/storage/fatfs/configs/phytiumpi_aarch64_firefly_fatfs.config +++ b/example/storage/fatfs/configs/phytiumpi_aarch64_firefly_fatfs.config @@ -3,8 +3,8 @@ # Project Configuration # CONFIG_FATFS_BASIC_TEST=y -# CONFIG_FATFS_SPEED_TEST is not set -# CONFIG_FATFS_CYCLE_TEST is not set +CONFIG_FATFS_SPEED_TEST=y +CONFIG_FATFS_CYCLE_TEST=y # end of Project Configuration CONFIG_USE_FREERTOS=y @@ -40,7 +40,7 @@ CONFIG_GCC_CODE_MODEL_SMALL=y CONFIG_USE_CACHE=y CONFIG_USE_MMU=y -# CONFIG_BOOT_WITH_FLUSH_CACHE is not set +CONFIG_BOOT_WITH_FLUSH_CACHE=y # CONFIG_MMU_DEBUG_PRINTS is not set # end of Arm architecture configuration # end of Arch configuration @@ -62,7 +62,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -347,21 +346,11 @@ CONFIG_FATFS_RAM_DISK_SIZE_MB=500 CONFIG_FATFS_RAM_DISK_SECTOR_SIZE_BYTE=512 # end of RAM Disk Configuration -CONFIG_FATFS_SDMMC=y -CONFIG_FATFS_SDMMC_FSDIF_TF=y -CONFIG_FATFS_SDMMC_FSDIF_EMMC=y -CONFIG_FATFS_SDMMC_PARTITION=1 +# CONFIG_FATFS_SDMMC_FSDIF_TF is not set +# CONFIG_FATFS_SDMMC_FSDIF_EMMC is not set # CONFIG_FATFS_SDMMC_FSDMMC_TF is not set -CONFIG_FATFS_SATA_DISK=y - -# -# SATA Disk Configuration -# -# CONFIG_FATFS_FSATA is not set -# CONFIG_FATFS_FSATA_PCIE is not set -# end of SATA Disk Configuration - -CONFIG_FATFS_USB=y +# CONFIG_FATFS_SATA_DISK is not set +# CONFIG_FATFS_USB is not set CONFIG_FATFS_VOLUME_COUNT=10 # CONFIG_FATFS_LFN_NONE is not set CONFIG_FATFS_LFN_HEAP=y @@ -379,23 +368,7 @@ CONFIG_USE_TLSF=y # CONFIG_USE_LITTLE_FS is not set # CONFIG_USE_LVGL is not set # CONFIG_USE_FREEMODBUS is not set -CONFIG_USE_CHERRY_USB=y - -# -# CherryUSB Configuration -# -CONFIG_CHERRY_USB_PORT_XHCI=y -# CONFIG_CHERRY_USB_PORT_PHYTIUM_OTG is not set -CONFIG_CHERRYUSB_HOST=y -# CONFIG_CHERRYUSB_DEVICE is not set -CONFIG_CHERRY_USB_HOST_HUB=y -CONFIG_CHERRY_USB_HOST_MSC=y -# CONFIG_CHERRY_USB_HOST_HID is not set -# CONFIG_CHERRY_USB_HOST_VEDIO is not set -# CONFIG_CHERRY_USB_HOST_CDC is not set -# CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS is not set -# end of CherryUSB Configuration - +# CONFIG_USE_CHERRY_USB is not set CONFIG_USE_FSL_SDMMC=y # diff --git a/example/storage/fatfs/figures/test_1.png b/example/storage/fatfs/figures/test_1.png index 3bda1d0341a93c86f75eba6dccdd6c684dc56d65..b37b38e1472f4b47724b0494474535557869123d 100644 Binary files a/example/storage/fatfs/figures/test_1.png and b/example/storage/fatfs/figures/test_1.png differ diff --git a/example/storage/fatfs/figures/test_2.png b/example/storage/fatfs/figures/test_2.png index a9786c6c346160a80d703d2e5c6af286e11e7e91..292423bea4660a02b33ad5816e0d1ce50f657f1a 100644 Binary files a/example/storage/fatfs/figures/test_2.png and b/example/storage/fatfs/figures/test_2.png differ diff --git a/example/storage/fatfs/figures/test_3.png b/example/storage/fatfs/figures/test_3.png index f3f1014c46b51ca88c2335f5d100e15cf12638b6..5748a378ba9f1b736b45df25622dfdf250dfc4bd 100644 Binary files a/example/storage/fatfs/figures/test_3.png and b/example/storage/fatfs/figures/test_3.png differ diff --git a/example/storage/fatfs/figures/test_4.png b/example/storage/fatfs/figures/test_4.png index cd334840894e874b852dc562724d91883ad6e7d7..8d395f561cf3d5804606e354c8f1b962f31e4909 100644 Binary files a/example/storage/fatfs/figures/test_4.png and b/example/storage/fatfs/figures/test_4.png differ diff --git a/example/storage/fatfs/figures/test_5.png b/example/storage/fatfs/figures/test_5.png deleted file mode 100644 index 25a6b67cc779395c01be1868000dfcbf918bd0da..0000000000000000000000000000000000000000 Binary files a/example/storage/fatfs/figures/test_5.png and /dev/null differ diff --git a/example/storage/fatfs/inc/fatfs_examples.h b/example/storage/fatfs/inc/fatfs_examples.h index 04106731d5d0ddabec9f063a2ce13e49fd8f608f..9979e22c09cf7c7611e6968a53b59cdc3c2302d7 100644 --- a/example/storage/fatfs/inc/fatfs_examples.h +++ b/example/storage/fatfs/inc/fatfs_examples.h @@ -25,6 +25,9 @@ #ifndef FATFS_EXAMPLES_H #define FATFS_EXAMPLES_H +#include "ftypes.h" +#include "FreeRTOS.h" + #ifdef __cplusplus extern "C" { @@ -38,13 +41,13 @@ enum FFREERTOS_FATFS_USB_DISK = 3U, FFREERTOS_FATFS_SATA_DISK = 4U, FFREERTOS_FATFS_SATA_PCIE_DISK = 5U, - FFREERTOS_DISK_TYPE_NUM, }; /* fatfs run */ BaseType_t FFreeRTOSFatfsTest(void); +void FatfsExampleEntry(void); #ifdef __cplusplus } #endif diff --git a/example/storage/fatfs/main.c b/example/storage/fatfs/main.c index aaa3635813052227ea58c8adcd5c093ab32cec30..8989ea3bf25ac1b7758541f8c5d9354c4226414a 100644 --- a/example/storage/fatfs/main.c +++ b/example/storage/fatfs/main.c @@ -23,16 +23,20 @@ */ #include -#include "shell.h" -#include "shell_port.h" -#include "fatfs_examples.h" #include "sdkconfig.h" - +#include "FreeRTOS.h" +#include "task.h" +#include "fatfs_examples.h" #if defined(CONFIG_FATFS_SDMMC_FSDIF_TF) || defined(CONFIG_FATFS_SDMMC_FSDIF_EMMC) #include "fsdif_timing.h" #include "fsl_sdmmc.h" #endif +#if defined CONFIG_USE_LETTER_SHELL +#include "shell.h" +#include "shell_port.h" +#endif + int main(void) { BaseType_t ret; @@ -42,13 +46,25 @@ int main(void) SDMMC_OSAInit(); #endif - ret = FFreeRTOSFatfsTest(); - +#if defined CONFIG_USE_LETTER_SHELL ret = LSUserShellTask() ; if (ret != pdPASS) { goto FAIL_EXIT; } +#else + ret = xTaskCreate((TaskFunction_t)FatfsExampleEntry, + (const char *)"FatfsExampleEntry", + (uint16_t)4096, + NULL, + (UBaseType_t)2, + NULL); + + if (ret != pdPASS) + { + goto FAIL_EXIT; + } +#endif vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ diff --git a/example/storage/fatfs/makefile b/example/storage/fatfs/makefile index 1220aacd8e974d11cebfb98e296587e791522f34..ef630a72d3617eb9a4ecafd1f5767e7f121e296d 100644 --- a/example/storage/fatfs/makefile +++ b/example/storage/fatfs/makefile @@ -23,8 +23,8 @@ include $(FREERTOS_SDK_DIR)/tools/makeall.mk USR_BOOT_DIR ?= /mnt/d/tftboot image: - $(MAKE) clean - $(MAKE) all -j + @$(MAKE) -s clean + @$(MAKE) -s all -j @cp ./$(IMAGE_OUT_NAME).elf $(USR_BOOT_DIR)/freertos.elf ifdef CONFIG_OUTPUT_BINARY @cp ./$(IMAGE_OUT_NAME).bin $(USR_BOOT_DIR)/freertos.bin diff --git a/example/storage/fatfs/sdkconfig b/example/storage/fatfs/sdkconfig index dd87b0e5d944415e8e1d1f97ca9a8333f81bf34b..adcd5447d59c9d3d6618f7bd0bebecff250de30f 100644 --- a/example/storage/fatfs/sdkconfig +++ b/example/storage/fatfs/sdkconfig @@ -3,8 +3,8 @@ # Project Configuration # CONFIG_FATFS_BASIC_TEST=y -# CONFIG_FATFS_SPEED_TEST is not set -# CONFIG_FATFS_CYCLE_TEST is not set +CONFIG_FATFS_SPEED_TEST=y +CONFIG_FATFS_CYCLE_TEST=y # end of Project Configuration CONFIG_USE_FREERTOS=y @@ -40,7 +40,7 @@ CONFIG_GCC_CODE_MODEL_SMALL=y CONFIG_USE_CACHE=y CONFIG_USE_MMU=y -# CONFIG_BOOT_WITH_FLUSH_CACHE is not set +CONFIG_BOOT_WITH_FLUSH_CACHE=y # CONFIG_MMU_DEBUG_PRINTS is not set # end of Arm architecture configuration # end of Arch configuration @@ -62,7 +62,6 @@ CONFIG_F32BIT_MEMORY_LENGTH=0x80000000 CONFIG_F64BIT_MEMORY_ADDRESS=0x2000000000 CONFIG_F64BIT_MEMORY_LENGTH=0x800000000 CONFIG_TARGET_E2000=y -# CONFIG_USE_SPINLOCK is not set CONFIG_DEFAULT_DEBUG_PRINT_UART1=y # CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set # CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set @@ -347,21 +346,11 @@ CONFIG_FATFS_RAM_DISK_SIZE_MB=500 CONFIG_FATFS_RAM_DISK_SECTOR_SIZE_BYTE=512 # end of RAM Disk Configuration -CONFIG_FATFS_SDMMC=y -CONFIG_FATFS_SDMMC_FSDIF_TF=y -CONFIG_FATFS_SDMMC_FSDIF_EMMC=y -CONFIG_FATFS_SDMMC_PARTITION=1 +# CONFIG_FATFS_SDMMC_FSDIF_TF is not set +# CONFIG_FATFS_SDMMC_FSDIF_EMMC is not set # CONFIG_FATFS_SDMMC_FSDMMC_TF is not set -CONFIG_FATFS_SATA_DISK=y - -# -# SATA Disk Configuration -# -# CONFIG_FATFS_FSATA is not set -# CONFIG_FATFS_FSATA_PCIE is not set -# end of SATA Disk Configuration - -CONFIG_FATFS_USB=y +# CONFIG_FATFS_SATA_DISK is not set +# CONFIG_FATFS_USB is not set CONFIG_FATFS_VOLUME_COUNT=10 # CONFIG_FATFS_LFN_NONE is not set CONFIG_FATFS_LFN_HEAP=y @@ -379,23 +368,7 @@ CONFIG_USE_TLSF=y # CONFIG_USE_LITTLE_FS is not set # CONFIG_USE_LVGL is not set # CONFIG_USE_FREEMODBUS is not set -CONFIG_USE_CHERRY_USB=y - -# -# CherryUSB Configuration -# -CONFIG_CHERRY_USB_PORT_XHCI=y -# CONFIG_CHERRY_USB_PORT_PHYTIUM_OTG is not set -CONFIG_CHERRYUSB_HOST=y -# CONFIG_CHERRYUSB_DEVICE is not set -CONFIG_CHERRY_USB_HOST_HUB=y -CONFIG_CHERRY_USB_HOST_MSC=y -# CONFIG_CHERRY_USB_HOST_HID is not set -# CONFIG_CHERRY_USB_HOST_VEDIO is not set -# CONFIG_CHERRY_USB_HOST_CDC is not set -# CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS is not set -# end of CherryUSB Configuration - +# CONFIG_USE_CHERRY_USB is not set CONFIG_USE_FSL_SDMMC=y # diff --git a/example/storage/fatfs/sdkconfig.h b/example/storage/fatfs/sdkconfig.h index 58bf7549503f990eafb6e7ffbe748a0ca25e3016..fd5d2c617211fef3c1739023903bcdb93c2e73d6 100644 --- a/example/storage/fatfs/sdkconfig.h +++ b/example/storage/fatfs/sdkconfig.h @@ -4,8 +4,8 @@ /* Project Configuration */ #define CONFIG_FATFS_BASIC_TEST -/* CONFIG_FATFS_SPEED_TEST is not set */ -/* CONFIG_FATFS_CYCLE_TEST is not set */ +#define CONFIG_FATFS_SPEED_TEST +#define CONFIG_FATFS_CYCLE_TEST /* end of Project Configuration */ #define CONFIG_USE_FREERTOS @@ -36,7 +36,7 @@ /* end of Compiler configuration */ #define CONFIG_USE_CACHE #define CONFIG_USE_MMU -/* CONFIG_BOOT_WITH_FLUSH_CACHE is not set */ +#define CONFIG_BOOT_WITH_FLUSH_CACHE /* CONFIG_MMU_DEBUG_PRINTS is not set */ /* end of Arm architecture configuration */ /* end of Arch configuration */ @@ -57,7 +57,6 @@ #define CONFIG_F64BIT_MEMORY_ADDRESS 0x2000000000 #define CONFIG_F64BIT_MEMORY_LENGTH 0x800000000 #define CONFIG_TARGET_E2000 -/* CONFIG_USE_SPINLOCK is not set */ #define CONFIG_DEFAULT_DEBUG_PRINT_UART1 /* CONFIG_DEFAULT_DEBUG_PRINT_UART0 is not set */ /* CONFIG_DEFAULT_DEBUG_PRINT_UART2 is not set */ @@ -304,19 +303,11 @@ #define CONFIG_FATFS_RAM_DISK_SIZE_MB 500 #define CONFIG_FATFS_RAM_DISK_SECTOR_SIZE_BYTE 512 /* end of RAM Disk Configuration */ -#define CONFIG_FATFS_SDMMC -#define CONFIG_FATFS_SDMMC_FSDIF_TF -#define CONFIG_FATFS_SDMMC_FSDIF_EMMC -#define CONFIG_FATFS_SDMMC_PARTITION 1 +/* CONFIG_FATFS_SDMMC_FSDIF_TF is not set */ +/* CONFIG_FATFS_SDMMC_FSDIF_EMMC is not set */ /* CONFIG_FATFS_SDMMC_FSDMMC_TF is not set */ -#define CONFIG_FATFS_SATA_DISK - -/* SATA Disk Configuration */ - -/* CONFIG_FATFS_FSATA is not set */ -/* CONFIG_FATFS_FSATA_PCIE is not set */ -/* end of SATA Disk Configuration */ -#define CONFIG_FATFS_USB +/* CONFIG_FATFS_SATA_DISK is not set */ +/* CONFIG_FATFS_USB is not set */ #define CONFIG_FATFS_VOLUME_COUNT 10 /* CONFIG_FATFS_LFN_NONE is not set */ #define CONFIG_FATFS_LFN_HEAP @@ -333,21 +324,7 @@ /* CONFIG_USE_LITTLE_FS is not set */ /* CONFIG_USE_LVGL is not set */ /* CONFIG_USE_FREEMODBUS is not set */ -#define CONFIG_USE_CHERRY_USB - -/* CherryUSB Configuration */ - -#define CONFIG_CHERRY_USB_PORT_XHCI -/* CONFIG_CHERRY_USB_PORT_PHYTIUM_OTG is not set */ -#define CONFIG_CHERRYUSB_HOST -/* CONFIG_CHERRYUSB_DEVICE is not set */ -#define CONFIG_CHERRY_USB_HOST_HUB -#define CONFIG_CHERRY_USB_HOST_MSC -/* CONFIG_CHERRY_USB_HOST_HID is not set */ -/* CONFIG_CHERRY_USB_HOST_VEDIO is not set */ -/* CONFIG_CHERRY_USB_HOST_CDC is not set */ -/* CONFIG_CHERRY_USB_HOST_RNDIS_WIRELESS is not set */ -/* end of CherryUSB Configuration */ +/* CONFIG_USE_CHERRY_USB is not set */ #define CONFIG_USE_FSL_SDMMC /* FSL Sdmmc configuration */ diff --git a/example/storage/fatfs/src/cmd_fatfs.c b/example/storage/fatfs/src/cmd_fatfs.c new file mode 100644 index 0000000000000000000000000000000000000000..f3098c07ac3692250b8dbf400333fdb443cc5221 --- /dev/null +++ b/example/storage/fatfs/src/cmd_fatfs.c @@ -0,0 +1,77 @@ +/* + * Copyright : (C) 2023 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: cmd_fatfs.c + * Date: 2024-04-25 14:53:42 + * LastEditTime: 2024-04-26 17:46:03 + * Description:  This file is for fatfs example cmd catalogue + * + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liyilun 2024/4/25 first release + */ + +/***************************** Include Files *********************************/ +#include +#include + +#include "sdkconfig.h" +#ifndef SDK_CONFIG_H__ + #warning "Please include sdkconfig.h" +#endif +#include "fatfs_examples.h" +#include "task.h" + +#ifdef CONFIG_USE_LETTER_SHELL +#include "shell.h" +#include "strto.h" + +static void FatfsCmdUsage() +{ + printf("Usage:\r\n"); + printf("fatfs test\r\n"); + printf("-- test fatfs on different peripherals\r\n"); +} + +static int FatfsCmdEntry(int argc, char *argv[]) +{ + int ret = 0; + + if (argc < 2) + { + FatfsCmdUsage(); + return -1; + } + + if (!strcmp(argv[1], "test")) + { + ret = FFreeRTOSFatfsTest(); + } + + return ret; +} +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), fatfs, FatfsCmdEntry, test freertos fatfs); + +#else + +void FatfsExampleEntry(void) +{ + FFreeRTOSFatfsTest(); + printf("[test_end].\r\n"); + vTaskDelete(NULL); +} + +#endif + + diff --git a/example/storage/fatfs/src/fatfs_examples.c b/example/storage/fatfs/src/fatfs_examples.c index 438c581df5fa2002765abed8630e8e067ff78363..861a449cc5d3c362833799d69ce7db63b40d0d2c 100644 --- a/example/storage/fatfs/src/fatfs_examples.c +++ b/example/storage/fatfs/src/fatfs_examples.c @@ -13,24 +13,22 @@ * * FilePath: fatfs_examples.c * Date: 2022-07-11 11:32:48 - * LastEditTime: 2022-07-11 11:32:48 + * LastEditTime: 2022-04-28 11:32:48 * Description: This file is for the fatfs test example functions. * * Modify History: * Ver   Who         Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 zhugengyu 2022/12/7 init commit + * 2.0 liyilun 2024/04/28 add no letter shell mode, adapt to auto test system */ #include #include #include - +#include "fatfs_examples.h" #include "FreeRTOSConfig.h" -#include "FreeRTOS.h" #include "task.h" -#include "semphr.h" -#include "timers.h" -#include "event_groups.h" +#include "queue.h" #include "fkernel.h" #include "strto.h" @@ -40,11 +38,14 @@ #include "sdkconfig.h" #include "ff_utils.h" -#include "fatfs_examples.h" + /************************** Constant Definitions *****************************/ #define FATFS_EVT_INIT_DONE (0x1 << 0) #define FATFS_EVT_CYC_TEST_DONE (0x1 << 1) +#define WR_SECTOR 3000U +#define RAM_WR_SECTOR 300000U +#define WAIT_TIMEOUT 1800000U /************************** Variable Definitions *****************************/ static const char *mount_points[FFREERTOS_DISK_TYPE_NUM] = { @@ -63,10 +64,9 @@ static const MKFS_PARM fs_option = .n_root = 0, .au_size = 0 }; -static boolean is_running = FALSE; -static EventGroupHandle_t sync = NULL; -static TimerHandle_t exit_timer = NULL; + static ff_fatfs file_sys[FFREERTOS_DISK_TYPE_NUM]; +static QueueHandle_t xQueue = NULL; /***************** Macros (Inline Functions) Definitions *********************/ #define FF_DEBUG_TAG "FATFS" @@ -78,34 +78,13 @@ static ff_fatfs file_sys[FFREERTOS_DISK_TYPE_NUM]; /************************** Function Prototypes ******************************/ /*****************************************************************************/ -static void FatfsSendEvent(u32 evt_bits) -{ - FASSERT(sync); - BaseType_t x_result = pdFALSE; - - FF_DEBUG("Ack evt_bits is 0x%x.", evt_bits); - x_result = xEventGroupSetBits(sync, evt_bits); -} -static boolean FatfsWaitEvent(u32 evt_bits, TickType_t wait_delay) -{ - FASSERT(sync); - EventBits_t ev; - ev = xEventGroupWaitBits(sync, evt_bits, - pdTRUE, pdFALSE, wait_delay); - if (ev & evt_bits) - { - return TRUE; - } - - return FALSE; -} - -static void FatfsInitTask(void *args) +static FRESULT FatfsInit(void) { FRESULT fr = FR_OK; #ifdef CONFIG_FATFS_RAM_DISK + printf("RAM init...\r\n"); fr = ff_setup(&file_sys[FFREERTOS_FATFS_RAM_DISK], mount_points[FFREERTOS_FATFS_RAM_DISK], &fs_option, pdTRUE); @@ -113,11 +92,12 @@ static void FatfsInitTask(void *args) if (FR_OK != fr) { FF_ERROR("RAM disk init failed, err = %d.", fr); - goto task_exit; + return fr; } #endif #ifdef CONFIG_FATFS_SDMMC_FSDIF_TF + printf("SDIF TF init...\r\n"); fr = ff_setup(&file_sys[FFREERTOS_FATFS_TF_CARD], mount_points[FFREERTOS_FATFS_TF_CARD], &fs_option, pdTRUE); @@ -125,11 +105,12 @@ static void FatfsInitTask(void *args) if (FR_OK != fr) { FF_ERROR("TF card init failed, err = %d.", fr); - goto task_exit; + return fr; } #endif #ifdef CONFIG_FATFS_SDMMC_FSDIF_EMMC + printf("SDIF EMMC init...\r\n"); fr = ff_setup(&file_sys[FFREERTOS_FATFS_EMMC_CARD], mount_points[FFREERTOS_FATFS_EMMC_CARD], &fs_option, pdTRUE); @@ -137,11 +118,12 @@ static void FatfsInitTask(void *args) if (FR_OK != fr) { FF_ERROR("eMMC card init failed, err = %d.", fr); - goto task_exit; + return fr; } #endif #ifdef CONFIG_FATFS_USB + printf("USB init...\r\n"); fr = ff_setup(&file_sys[FFREERTOS_FATFS_USB_DISK], mount_points[FFREERTOS_FATFS_USB_DISK], &fs_option, pdTRUE); @@ -149,11 +131,12 @@ static void FatfsInitTask(void *args) if (FR_OK != fr) { FF_ERROR("USB init failed, err = %d.", fr); - goto task_exit; + return fr; } #endif #ifdef CONFIG_FATFS_FSATA + printf("SATA init...\r\n"); fr = ff_setup(&file_sys[FFREERTOS_FATFS_SATA_DISK], mount_points[FFREERTOS_FATFS_SATA_DISK], &fs_option, pdTRUE); @@ -161,10 +144,11 @@ static void FatfsInitTask(void *args) if (FR_OK != fr) { FF_ERROR("SATA init failed, err = %d.", fr); - goto task_exit; + return fr; } #endif #ifdef CONFIG_FATFS_FSATA_PCIE + printf("SATA PCIE...\r\n"); fr = ff_setup(&file_sys[FFREERTOS_FATFS_SATA_PCIE_DISK], mount_points[FFREERTOS_FATFS_SATA_PCIE_DISK], &fs_option, pdTRUE); @@ -172,32 +156,24 @@ static void FatfsInitTask(void *args) if (FR_OK != fr) { FF_ERROR("SATA PCIE init failed, err = %d.", fr); - goto task_exit; + return fr; } #endif - printf("Storage device init finished !!!\r\n"); - FatfsSendEvent(FATFS_EVT_INIT_DONE); -task_exit: - vTaskDelete(NULL); /* delete task itself */ + return FR_OK; } -static void FatfsTestTask(void *args) + +static FRESULT FatfsBasicTest(void) { - const char *root = NULL; FRESULT fr = FR_OK; - - FatfsWaitEvent(FATFS_EVT_INIT_DONE, portMAX_DELAY); - -#ifdef CONFIG_FATFS_BASIC_TEST - { #ifdef CONFIG_FATFS_RAM_DISK printf("\r\n========Basic test for RAM Disk=================\r\n"); fr = ff_basic_test(mount_points[FFREERTOS_FATFS_RAM_DISK], "logfile.txt"); if (FR_OK != fr) { FF_ERROR("RAM disk basic test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif @@ -207,7 +183,7 @@ static void FatfsTestTask(void *args) if (FR_OK != fr) { FF_ERROR("TF card basic test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif @@ -217,7 +193,7 @@ static void FatfsTestTask(void *args) if (FR_OK != fr) { FF_ERROR("SDIO basic test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif @@ -227,7 +203,7 @@ static void FatfsTestTask(void *args) if (FR_OK != fr) { FF_ERROR("USB basic test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif @@ -237,7 +213,7 @@ static void FatfsTestTask(void *args) if (FR_OK != fr) { FF_ERROR("SATA basic test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif @@ -247,187 +223,211 @@ static void FatfsTestTask(void *args) if (FR_OK != fr) { FF_ERROR("SATA PCIE basic test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif - } -#endif + return fr; +} + /* speed test will test diskio and destory file system */ -#ifdef CONFIG_FATFS_SPEED_TEST - { +static FRESULT FatfsSpeedTest(void) +{ + FRESULT fr = FR_OK; #ifdef CONFIG_FATFS_RAM_DISK printf("\r\n========Speed test for RAM Disk=================\r\n"); - fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_RAM_DISK], 300000U); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_RAM_DISK], RAM_WR_SECTOR); if (FR_OK != fr) { FF_ERROR("RAM disk speed test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif #ifdef CONFIG_FATFS_SDMMC_FSDIF_TF printf("\r\n========Speed test for TF Card=================\r\n"); - fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_TF_CARD], 300000U); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_TF_CARD], WR_SECTOR); if (FR_OK != fr) { FF_ERROR("TF speed test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif #ifdef CONFIG_FATFS_SDMMC_FSDIF_EMMC printf("\r\n========Speed test for eMMC=================\r\n"); - fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_EMMC_CARD], 300000U); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_EMMC_CARD], WR_SECTOR); if (FR_OK != fr) { FF_ERROR("SDIO speed test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif #ifdef CONFIG_FATFS_USB printf("\r\n========Speed test for USB Disk=================\r\n"); - fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_USB_DISK], 300000U); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_USB_DISK], WR_SECTOR); + printf("Speed test for USB end\r\n"); if (FR_OK != fr) { FF_ERROR("USB speed test failed, err = %d.", fr); - goto task_exit; + return fr; } + #endif #ifdef CONFIG_FATFS_FSATA printf("\r\n========Speed test for SATA Disk=================\r\n"); - fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_SATA_DISK], 30000U); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_SATA_DISK], WR_SECTOR); if (FR_OK != fr) { FF_ERROR("SATA speed test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif #ifdef CONFIG_FATFS_FSATA_PCIE printf("\r\n========Speed test for SATA PCIE Disk=================\r\n"); - fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_SATA_PCIE_DISK], 30000U); + fr = ff_speed_bench(mount_points[FFREERTOS_FATFS_SATA_PCIE_DISK], WR_SECTOR); if (FR_OK != fr) { FF_ERROR("SATA PCIE speed test failed, err = %d.", fr); - goto task_exit; + return fr; } #endif - } -#endif + return fr; +} - /* cycle test will test diskio and destory file system */ -#ifdef CONFIG_FATFS_CYCLE_TEST - { +/* cycle test will test diskio and destory file system */ +static FRESULT FatfsCycleTest(void) +{ + FRESULT fr = FR_OK; #ifdef CONFIG_FATFS_RAM_DISK printf("\r\n========Cycle test for RAM Disk=================\r\n"); - if (ff_cycle_test(mount_points[FFREERTOS_FATFS_RAM_DISK], 3)) + fr = ff_cycle_test(mount_points[FFREERTOS_FATFS_RAM_DISK], 3); + if (FR_OK != fr) { - goto task_exit; + FF_ERROR("RAM cycle test failed, err = %d.", fr); + return fr; } #endif #ifdef CONFIG_FATFS_SDMMC_FSDIF_TF printf("\r\n========Cycle test for TF Disk=================\r\n"); - if (ff_cycle_test(mount_points[FFREERTOS_FATFS_TF_CARD], 3)) + fr = ff_cycle_test(mount_points[FFREERTOS_FATFS_TF_CARD], 3); + if (FR_OK != fr) { - goto task_exit; + FF_ERROR("TF cycle test failed, err = %d.", fr); + return fr; } #endif #ifdef CONFIG_FATFS_SDMMC_FSDIF_EMMC printf("\r\n========Cycle test for SDIO Disk=================\r\n"); - if (ff_cycle_test(mount_points[FFREERTOS_FATFS_EMMC_CARD], 3)) + fr = ff_cycle_test(mount_points[FFREERTOS_FATFS_EMMC_CARD], 3); + if (FR_OK != fr) { - goto task_exit; + FF_ERROR("SDIO cycle test failed, err = %d.", fr); + return fr; } + #endif #ifdef CONFIG_FATFS_USB printf("\r\n========Cycle test for USB Disk=================\r\n"); - if (ff_cycle_test(mount_points[FFREERTOS_FATFS_USB_DISK], 3)) + fr = ff_cycle_test(mount_points[FFREERTOS_FATFS_USB_DISK], 3); + if (FR_OK != fr) { - goto task_exit; + FF_ERROR("USB cycle test failed, err = %d.", fr); + return fr; } #endif #ifdef CONFIG_FATFS_FSATA printf("\r\n========Cycle test for SATA Disk=================\r\n"); - if (ff_cycle_test(mount_points[FFREERTOS_FATFS_SATA_DISK], 3)) + fr = ff_cycle_test(mount_points[FFREERTOS_FATFS_SATA_DISK], 3); + if (FR_OK != fr) { - goto task_exit; + FF_ERROR("SATA cycle test failed, err = %d.", fr); + return fr; } #endif #ifdef CONFIG_FATFS_FSATA_PCIE printf("\r\n========Cycle test for SATA PCIE Disk=================\r\n"); - if (ff_cycle_test(mount_points[FFREERTOS_FATFS_SATA_PCIE_DISK], 3)) + fr = ff_cycle_test(mount_points[FFREERTOS_FATFS_SATA_PCIE_DISK], 3); + if (FR_OK != fr) { - goto task_exit; + FF_ERROR("SATA pcie cycle test failed, err = %d.", fr); + return fr; } #endif - } -#endif - -task_exit: - FatfsSendEvent(FATFS_EVT_CYC_TEST_DONE); - printf("Exit from test task.\r\n"); - vTaskDelete(NULL); /* delete task itself */ + return fr; } -static void FatfsExitCallback(TimerHandle_t timer) +void FatfsRunTask(void) { - if (sync) + FRESULT fret = FR_OK; + fret = FatfsInit(); + if(FR_OK != fret) + { + goto task_ret; + } + +#ifdef CONFIG_FATFS_BASIC_TEST + fret = FatfsBasicTest(); + if(FR_OK != fret) { - vEventGroupDelete(sync); - sync = NULL; + goto task_ret; } +#endif - is_running = FALSE; +#ifdef CONFIG_FATFS_SPEED_TEST + fret = FatfsSpeedTest(); + if(FR_OK != fret) + { + goto task_ret; + } +#endif + +#ifdef CONFIG_FATFS_CYCLE_TEST + fret = FatfsCycleTest(); + if(FR_OK != fret) + { + goto task_ret; + } +#endif +task_ret: + xQueueSend(xQueue, &fret, 0); + vTaskDelete(NULL); } BaseType_t FFreeRTOSFatfsTest(void) { BaseType_t ret = pdPASS; - const TickType_t total_run_time = pdMS_TO_TICKS(30000UL); /* run for 30 secs deadline */ - - if (is_running) - { - FF_ERROR("The task is running."); - return pdPASS; - } - - FASSERT_MSG(NULL == sync, "Event group exists."); - FASSERT_MSG((sync = xEventGroupCreate()) != NULL, "Create event group failed."); - - taskENTER_CRITICAL(); /* no schedule when create task */ - - ret = xTaskCreate((TaskFunction_t)FatfsInitTask, - (const char *)"FatfsInitTask", - (uint16_t)2048, - NULL, - (UBaseType_t)configMAX_PRIORITIES - 1, - NULL); - FASSERT_MSG(pdPASS == ret, "Create task failed."); + int task_ret = FR_OK; + xQueue = xQueueCreate(1,sizeof(int)); - ret = xTaskCreate((TaskFunction_t)FatfsTestTask, - (const char *)"FatfsTestTask", + ret = xTaskCreate((TaskFunction_t)FatfsRunTask, + (const char *)"FatfsRunTask", (uint16_t)2048, NULL, (UBaseType_t)configMAX_PRIORITIES - 1, NULL); FASSERT_MSG(pdPASS == ret, "Create task failed."); - exit_timer = xTimerCreate("FatfsExitTimer", /* Text name for the software timer - not used by FreeRTOS. */ - total_run_time, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - NULL, /* use timer id to pass task data for reference. */ - FatfsExitCallback); /* The callback function to be used by the software timer being created. */ - - FASSERT_MSG(NULL != exit_timer, "Create exit timer failed."); + ret = xQueueReceive(xQueue, &task_ret, WAIT_TIMEOUT); + FASSERT_MSG(pdPASS == ret, "xQueue Receive failed.\r\n"); - taskEXIT_CRITICAL(); /* allow schedule since task created */ - return ret; + vQueueDelete(xQueue); + if(task_ret != FR_OK) + { + printf("%s@%d: fatfs example [failure].\r\n", __func__, __LINE__); + return pdFAIL; + } + else + { + printf("%s@%d: fatfs example [success].\r\n", __func__, __LINE__); + return pdTRUE; + } } \ No newline at end of file diff --git a/example/storage/qspi_spiffs/README.md b/example/storage/qspi_spiffs/README.md index d95cfdf575a613cdd5a21a53ea725d052e605dc0..a2045b27ef0c1677245add13b40cb73a170a06fd 100644 --- a/example/storage/qspi_spiffs/README.md +++ b/example/storage/qspi_spiffs/README.md @@ -18,8 +18,8 @@ - 3. 支持的 Flash 容量不能超过 128 MB - 4. 不支持坏块检测和坏块处理 -本例程通过Freertos下的SPIFFS测试,验证了QSPI Nor-flash文件系统的基本功能,如文件系统格式化,文件的创建、读写、删除和枚举等,例程在FT2000/4上测试通过,使用的Nor Flash介质型号是GD25LQ256E,容量为32MB; -E2000D上使用的Nor Flash介质型号是GD25LQ128E,容量为16MB; +本例程通过Freertos下的SPIFFS测试,验证了QSPI Nor-flash文件系统的基本功能,如文件系统格式化,文件的创建、读写、删除和枚举等,例程在E2000D DEMO上测试通过,使用的Nor Flash介质型号是GD25LQ128E,容量为16MB; +FT2000/4上使用的Nor Flash介质型号是GD25LQ256E,容量为32MB; ## 2. 如何使用例程 @@ -43,6 +43,10 @@ E2000D上使用的Nor Flash介质型号是GD25LQ128E,容量为16MB; ![hardware](./figs/hardware.png) +- PhytiumPi,若未安装qspi-flash芯片插槽,请自行安装 + +![phytiumpi_hardware](./figs/phytiumpi_hardware.png) + ### 2.2 SDK配置方法 >依赖哪些驱动、库和第三方组件,如何完成配置(列出需要使能的关键配置项)
@@ -98,19 +102,12 @@ bootelf -p 0x90100000 >描述输入输出情况,列出存在哪些输出,对应的输出是什么(建议附录相关现象图片)
-程序启动后,依次创建Init、WriteRead任务,创建单次模式软件定时器用于删除任务,Init任务会首先初始化并挂载qspi flash的部分区域(可通过FSPIFFS_IF_FORMAT选择是否进行格式化操作),随后创建一个文件,然后释放信号量通知WriteRead任务开始执行; - -- init完成,挂载文件系统完成,创建测试文件 - -![init](./figs/init.png) - -- 读写任务周期性执行 +程序启动后,依次创建Init、WriteRead任务,Init任务会首先初始化并挂载qspi flash的部分区域(可通过FSPIFFS_IF_FORMAT选择是否进行格式化操作),随后创建一个文件,然后WriteRead任务开始执行; -![wr](./figs/wr.png) +- init完成,挂载文件系统完成,创建测试文件,进行写数据和读数据 -- 软件定时器触发,删除读写任务 +![qspi_spiffs_test_result](./figs/qspi_spiffs_test_result.png) -![delete](./figs/delete.png) ## 3. 如何解决问题 diff --git a/example/storage/qspi_spiffs/figs/hardware.png b/example/storage/qspi_spiffs/figs/hardware.png index 0b79eed2aa5697b267998627808484c2688eefd2..570b1746b9b5c8d4ba687f30029233a0e1f81098 100644 Binary files a/example/storage/qspi_spiffs/figs/hardware.png and b/example/storage/qspi_spiffs/figs/hardware.png differ diff --git a/example/storage/qspi_spiffs/figs/phytiumpi_hardware.png b/example/storage/qspi_spiffs/figs/phytiumpi_hardware.png new file mode 100644 index 0000000000000000000000000000000000000000..4d44fc80c7d309b355eee8a71b6bd30a7b7d25bc Binary files /dev/null and b/example/storage/qspi_spiffs/figs/phytiumpi_hardware.png differ diff --git a/example/storage/qspi_spiffs/figs/qspi_spiffs_test_result.png b/example/storage/qspi_spiffs/figs/qspi_spiffs_test_result.png new file mode 100644 index 0000000000000000000000000000000000000000..bbf1809ce36fb8b669a43ec7a5ec8cc6f09bb241 Binary files /dev/null and b/example/storage/qspi_spiffs/figs/qspi_spiffs_test_result.png differ diff --git a/example/storage/qspi_spiffs/inc/qspi_spiffs_example.h b/example/storage/qspi_spiffs/inc/qspi_spiffs_example.h index 309a94236864033da269860db62704f4aaa1d570..873c559779a2a3705f34484c8072c61a81b5dade 100644 --- a/example/storage/qspi_spiffs/inc/qspi_spiffs_example.h +++ b/example/storage/qspi_spiffs/inc/qspi_spiffs_example.h @@ -25,13 +25,15 @@ #ifndef QSPI_SPIFFS_EXAMPLE_H #define QSPI_SPIFFS_EXAMPLE_H +#include "portmacro.h" + #ifdef __cplusplus extern "C" { #endif /* qspi spiffs read and write test */ -BaseType_t FFreeRTOSQspiSpiffsCreate(u32 qspi_id); +int FFreeRTOSQspiSpiffsCreate(void); #ifdef __cplusplus diff --git a/example/storage/qspi_spiffs/main.c b/example/storage/qspi_spiffs/main.c index e26855e907feca80004c88aca4aa55aa1066e1a6..a5dde0f5a5a246f22103ce63e96c664b0a042483 100644 --- a/example/storage/qspi_spiffs/main.c +++ b/example/storage/qspi_spiffs/main.c @@ -19,25 +19,48 @@ * Modify History: * Ver    Who         Date          Changes * -----  ------       --------    -------------------------------------- - * 1.0 wangxiaodong 2022/8/9 first release + * 1.0 wangxiaodong 2022/8/9 first release + * 2.0 huangjin 2024/4/25 add no letter shell mode, adapt to auto-test system */ +#include +#include "FreeRTOS.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include +#else +#include "task.h" #include "qspi_spiffs_example.h" -int main(void) +#define QSPI_SPIFFS_EXAMPLE_TASK_PRIORITY 2 + +void QspiSpiffsExampleTaskEntry(void *pvParameters) { - BaseType_t ret; + /* example functions */ + FFreeRTOSQspiSpiffsCreate(); - ret = FFreeRTOSQspiSpiffsCreate(0); - if (ret != pdPASS) - { - goto FAIL_EXIT; - } + /* end flag */ + printf("[test_end]\r\n"); + vTaskDelete(NULL); +} +#endif + +int main(void) +{ + BaseType_t ret = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - ret = LSUserShellTask() ; +#ifdef CONFIG_USE_LETTER_SHELL + ret = LSUserShellTask(); +#else + /* used in no-letter-shell mode */ + ret = xTaskCreate((TaskFunction_t)QspiSpiffsExampleTaskEntry, /* 任务入口函数 */ + (const char *)"QspiSpiffsExampleTaskEntry",/* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)QSPI_SPIFFS_EXAMPLE_TASK_PRIORITY, /* 任务的优先级 */ + NULL); +#endif if (ret != pdPASS) { goto FAIL_EXIT; @@ -47,6 +70,6 @@ int main(void) while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("Failed,the ret value is 0x%x. \r\n", ret); + printf("Qspi spiffs example failed in main.c, the ret value is 0x%x. \r\n", ret); return 0; } diff --git a/example/storage/qspi_spiffs/src/cmd_qspi_spiffs.c b/example/storage/qspi_spiffs/src/cmd_qspi_spiffs.c new file mode 100644 index 0000000000000000000000000000000000000000..c164f5fc1cacff2e90b2a6ef6a659b7074a986c3 --- /dev/null +++ b/example/storage/qspi_spiffs/src/cmd_qspi_spiffs.c @@ -0,0 +1,71 @@ +/* + * Copyright : (C) 2022 Phytium Information Technology, Inc. + * All Rights Reserved. + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it + * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd, + * either version 1.0 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Phytium Public License for more details. + * + * + * FilePath: cmd_qspi_spiffs.c + * Date: 2024-04-25 14:06:43 + * LastEditTime: 2024-04-25 14:06:43 + * Description:  This files is for qspi spiffs command interface + * + * Modify History: + * Ver    Who         Date         Changes + * -----  ------      --------     -------------------------------------- + * 1.0 huangjin 2024/04/25 add no letter shell mode, adapt to auto-test system + */ + +/***************************** Include Files *********************************/ +#include +#include +#include "strto.h" + +#include "sdkconfig.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "../src/shell.h" + +#include "qspi_spiffs_example.h" +#endif +/************************** Constant Definitions *****************************/ + +/************************** Variable Definitions *****************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +#ifdef CONFIG_USE_LETTER_SHELL +static void QspiSpiffsCmdUsage() +{ + printf("Usage:\r\n"); + printf("qspi_spiffs write_read\r\n"); + printf("-- Demo write and read by qspi_spiffs\r\n"); +} + +static int QspiSpiffsCmdEntry(int argc, char *argv[]) +{ + int ret = 0; + + if (argc < 2) + { + QspiSpiffsCmdUsage(); + return -1; + } + + if (!strcmp(argv[1], "write_read")) + { + ret = FFreeRTOSQspiSpiffsCreate(); + } + + return ret; +} +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), qspi_spiffs, QspiSpiffsCmdEntry, test freertos qspi_spiffs); +#endif \ No newline at end of file diff --git a/example/storage/qspi_spiffs/src/qspi_spiffs_example.c b/example/storage/qspi_spiffs/src/qspi_spiffs_example.c index e2c90e738e00138fd1f2c09a0a620a6cf88e6e04..4ae790d69b368cfa5e4205c5a1213381e5ea0e15 100644 --- a/example/storage/qspi_spiffs/src/qspi_spiffs_example.c +++ b/example/storage/qspi_spiffs/src/qspi_spiffs_example.c @@ -13,7 +13,7 @@ * * FilePath: qspi_spiffs_example.c * Date: 2022-07-11 11:32:48 - * LastEditTime: 2022-07-11 11:32:48 + * LastEditTime: 2024-04-26 11:32:48 * Description: This file is for the qspi_spiffs example functions. * * Modify History: @@ -21,6 +21,7 @@ * -----  ------       --------    -------------------------------------- * 1.0 wangxiaodong 2022/8/9 first release * 1.1 zhangyan 2023/2/9 improve functions + * 1.2 huangjin 2024/4/26 add no letter shell mode, adapt to auto-test system */ #include #include @@ -29,11 +30,9 @@ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "semphr.h" +#include "queue.h" #include "fio_mux.h" -#include "timers.h" #include "qspi_spiffs_example.h" -#include "strto.h" #include "fassert.h" #include "fdebug.h" #include "fparameters.h" @@ -61,6 +60,8 @@ enum FSPIFFS_OPS_READ_FILE_FAILED, FSPIFFS_OPS_REMOVE_FILE_FAILED, FSPIFFS_OPS_CLOSE_FILE_FAILED, + FSPIFFS_OPS_UNKNOWN_STATE, + FSPIFFS_OPS_DATA_FAILED, }; #define FSPIFFS_DEBUG_TAG "SPIFFS-QSPI" @@ -70,9 +71,9 @@ enum #define FSPIFFS_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSPIFFS_DEBUG_TAG, format, ##__VA_ARGS__) /* spiffs start address and size */ -#if defined(CONFIG_TARGET_E2000) +#if defined(CONFIG_E2000D_DEMO_BOARD) || defined(CONFIG_E2000Q_DEMO_BOARD) || defined(CONFIG_FIREFLY_DEMO_BOARD) #define FSPIFFS_START_ADDR (3 * SZ_1M) -#elif defined(CONFIG_TARGET_FT2004) || defined(CONFIG_TARGET_D2000) +#elif defined(CONFIG_FT2004_DSK_BOARD) || defined(CONFIG_D2000_TEST_BOARD) #define FSPIFFS_START_ADDR (7 * SZ_1M) #endif @@ -83,6 +84,10 @@ enum /* if format flash, TRUE is need format, it tasks some time */ #define FSPIFFS_IF_FORMAT TRUE +#define QSPI_SPIFFS_WRITE_READ_TASK_PRIORITY 3 + +#define TIMER_OUT (pdMS_TO_TICKS(4000UL)) + /* 一个页大小两倍的一个RAM缓冲区, 用来加载和维护SPIFFS的逻辑页 */ static volatile u8 fspiffs_work_buf[FSPIFFS_LOG_PAGE_SIZE * 2] = {0}; static volatile u8 fspiffs_fds_buf[32 * 4] = {0}; @@ -95,20 +100,7 @@ static boolean spiffs_inited = FALSE; const char *file_name = "test.txt"; /************************** Constant Definitions *****************************/ - -/* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 50000UL ) ) - -/* write and read task delay in milliseconds */ -#define TASK_DELAY_MS 3000UL - -/* write and read task number */ -#define READ_WRITE_TASK_NUM 1 -static xSemaphoreHandle xCountingSemaphore; - -static xTaskHandle qspi_rw_handle; - -static TimerHandle_t xOneShotTimer; +static QueueHandle_t xQueue = NULL; static const char *xString = "FFreeRTOSQspiSpiffsWriteReadTask is running\r\n"; @@ -166,7 +158,7 @@ static int FSpiffsOpsMount(boolean do_format) } else { - vPrintf("Mount spiffs success. \r\n"); + FSPIFFS_INFO("Mount spiffs success. \r\n"); instance.fs_ready = TRUE; } @@ -206,9 +198,9 @@ static int FSpiffsOpsListAll(void) return ret; } -int FSpiffsOpsCreateFile(const char *file_name) +int FSpiffsOpsCreateFile(const char *create_file_name) { - FASSERT((file_name) && (strlen(file_name) > 0)); + FASSERT((create_file_name) && (strlen(create_file_name) > 0)); if (FALSE == instance.fs_ready) { FSPIFFS_ERROR("Please mount file system first."); @@ -218,18 +210,18 @@ int FSpiffsOpsCreateFile(const char *file_name) int ret = FSPIFFS_OPS_OK; /* create file */ - s32_t result = SPIFFS_creat(&instance.fs, file_name, 0); + s32_t result = SPIFFS_creat(&instance.fs, create_file_name, 0); if (result < 0) { - FSPIFFS_ERROR("Failed to create file %s", file_name); + FSPIFFS_ERROR("Failed to create file %s", create_file_name); return FSPIFFS_OPS_OPEN_FILE_FAILED; } /* open file */ - spiffs_file fd = SPIFFS_open(&instance.fs, file_name, SPIFFS_RDONLY, 0); + spiffs_file fd = SPIFFS_open(&instance.fs, create_file_name, SPIFFS_RDONLY, 0); if (0 > fd) { - FSPIFFS_ERROR("Failed to open file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to open file %s errno %d", create_file_name, SPIFFS_errno(&instance.fs)); return FSPIFFS_OPS_OPEN_FILE_FAILED; } @@ -239,14 +231,14 @@ int FSpiffsOpsCreateFile(const char *file_name) result = SPIFFS_fstat(&instance.fs, fd, &status); if (result < 0) { - FSPIFFS_ERROR("Failed to get status of file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to get status of file %s, errno %d", create_file_name, SPIFFS_errno(&instance.fs)); ret = FSPIFFS_OPS_OPEN_FILE_FAILED; goto err_exit; } - if (0 != strcmp(status.name, file_name)) + if (0 != strcmp(status.name, create_file_name)) { - FSPIFFS_ERROR("Created file name %s != %s", status.name, file_name); + FSPIFFS_ERROR("Created file name %s != %s", status.name, create_file_name); ret = FSPIFFS_OPS_OPEN_FILE_FAILED; goto err_exit; } @@ -258,31 +250,31 @@ int FSpiffsOpsCreateFile(const char *file_name) goto err_exit; } - vPrintf("File %s created successfully.\r\n", file_name); + FSPIFFS_INFO("File %s created successfully.\r\n", create_file_name); err_exit: (void)SPIFFS_close(&instance.fs, fd); return ret; } -int FSpiffsOpsWriteFile(const char *file_name, const char *str) +int FSpiffsOpsWriteFile(const char *write_file_name, const char *str) { - FASSERT((file_name) && (strlen(file_name) > 0)); + FASSERT((write_file_name) && (strlen(write_file_name) > 0)); FASSERT(str); int ret = FSPIFFS_OPS_OK; const u32 wr_len = strlen(str) + 1; - spiffs_file fd = SPIFFS_open(&instance.fs, file_name, SPIFFS_RDWR | SPIFFS_TRUNC, 0); + spiffs_file fd = SPIFFS_open(&instance.fs, write_file_name, SPIFFS_RDWR | SPIFFS_TRUNC, 0); if (0 > fd) { - FSPIFFS_ERROR("Failed to open file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to open file %s, errno %d", write_file_name, SPIFFS_errno(&instance.fs)); return FSPIFFS_OPS_OPEN_FILE_FAILED; } int result = SPIFFS_write(&instance.fs, fd, (void *)str, wr_len); if (result < 0) { - FSPIFFS_ERROR("Failed to write file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to write file %s, errno %d", write_file_name, SPIFFS_errno(&instance.fs)); ret = FSPIFFS_OPS_WRITE_FILE_FAILED; goto err_exit; } @@ -293,7 +285,7 @@ int FSpiffsOpsWriteFile(const char *file_name, const char *str) result = SPIFFS_fstat(&instance.fs, fd, &status); if (result < 0) { - FSPIFFS_ERROR("Failed to get status of file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to get status of file %s, errno %d", write_file_name, SPIFFS_errno(&instance.fs)); ret = FSPIFFS_OPS_WRITE_FILE_FAILED; goto err_exit; } @@ -307,15 +299,15 @@ int FSpiffsOpsWriteFile(const char *file_name, const char *str) /* flush all pending writes from cache to flash */ (void)SPIFFS_fflush(&instance.fs, fd); - vPrintf("Write file %s with %d bytes successfully.\r\n", file_name, wr_len); + FSPIFFS_INFO("Write file %s with %d bytes successfully.\r\n", write_file_name, wr_len); err_exit: (void)SPIFFS_close(&instance.fs, fd); return ret; } -int FSpiffsOpsReadFile(const char *file_name) +int FSpiffsOpsReadFile(const char *read_file_name) { - FASSERT((file_name) && (strlen(file_name) > 0)); + FASSERT((read_file_name) && (strlen(read_file_name) > 0)); int ret = FSPIFFS_OPS_OK; int result = SPIFFS_OK; @@ -332,10 +324,10 @@ int FSpiffsOpsReadFile(const char *file_name) /* open the file in read-only mode */ open_flags = SPIFFS_RDWR; - spiffs_file fd = SPIFFS_open(&instance.fs, file_name, open_flags, 0); + spiffs_file fd = SPIFFS_open(&instance.fs, read_file_name, open_flags, 0); if (0 > fd) { - FSPIFFS_ERROR("Failed to open file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to open file %s, errno %d", read_file_name, SPIFFS_errno(&instance.fs)); return FSPIFFS_OPS_OPEN_FILE_FAILED; } @@ -344,7 +336,7 @@ int FSpiffsOpsReadFile(const char *file_name) result = SPIFFS_fstat(&instance.fs, fd, &status); if (result < 0) { - FSPIFFS_ERROR("Failed to get status of file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to get status of file %s, errno %d", read_file_name, SPIFFS_errno(&instance.fs)); ret = FSPIFFS_OPS_OPEN_FILE_FAILED; goto err_exit; } @@ -352,7 +344,7 @@ int FSpiffsOpsReadFile(const char *file_name) s32_t offset = SPIFFS_lseek(&instance.fs, fd, 0, SPIFFS_SEEK_END); if ((s32_t)status.size != offset) { - FSPIFFS_ERROR("File %s spiffs:%ld != fs:%ld", file_name, status.size, offset); + FSPIFFS_ERROR("File %s spiffs:%ld != fs:%ld", read_file_name, status.size, offset); ret = FSPIFFS_OPS_OPEN_FILE_FAILED; goto err_exit; } @@ -372,12 +364,12 @@ int FSpiffsOpsReadFile(const char *file_name) s32_t read_bytes = SPIFFS_read(&instance.fs, fd, (void *)fspiffs_rd_buf, read_len); if (read_bytes < 0) { - FSPIFFS_ERROR("Failed to read file %s, errno %d", file_name, SPIFFS_errno(&instance.fs)); + FSPIFFS_ERROR("Failed to read file %s, errno %d", read_file_name, SPIFFS_errno(&instance.fs)); ret = FSPIFFS_OPS_READ_FILE_FAILED; goto err_exit; } - vPrintf("Read %s success, str = %s\n", file_name, fspiffs_rd_buf); + FSPIFFS_INFO("Read %s success, str = %s\n", read_file_name, fspiffs_rd_buf); err_exit : /* close file */ @@ -387,24 +379,20 @@ err_exit : } -static void FFreeRTOSQspiSpiffsInitTask(void *pvParameters) +static FError QspiSpiffsInit(void) { + FError init_ret = FSPIFFS_OPS_INIT_FAILED; int result = 0; if (TRUE == spiffs_inited) { FSPIFFS_WARN("Spiffs is already initialized."); - return; + return FSPIFFS_OPS_ALREADY_INITED; } - /* The qspi_id to use is passed in via the parameter. - Cast this to a qspi_id pointer. */ - u32 qspi_id = (u32)(uintptr)pvParameters; - printf("qspi_id: %d\n", qspi_id); FIOMuxInit(); -#if defined(CONFIG_TARGET_E2000) - FIOPadSetQspiMux(qspi_id, FQSPI_CS_0); - FIOPadSetQspiMux(qspi_id, FQSPI_CS_1); +#if defined(CONFIG_E2000D_DEMO_BOARD) + FIOPadSetQspiMux(FSPI0_ID, FQSPI_CS_0); #endif memset(&config, 0, sizeof(config)); @@ -420,7 +408,7 @@ static void FFreeRTOSQspiSpiffsInitTask(void *pvParameters) if (FSPIFFS_PORT_OK != result) { FSPIFFS_ERROR("Initialize spiffs failed."); - return; + return FSPIFFS_OPS_INIT_FAILED; } FSpiffsOpsMount(FSPIFFS_IF_FORMAT); @@ -433,156 +421,124 @@ static void FFreeRTOSQspiSpiffsInitTask(void *pvParameters) FSPIFFS_INFO("Spiffs init successfully."); - for (int i = 0; i < READ_WRITE_TASK_NUM; i++) - { - xSemaphoreGive(xCountingSemaphore); - } - - vTaskDelete(NULL); - + return FSPIFFS_OPS_OK; } -static void FFreeRTOSQspiSpiffsWriteReadTask(void *pvParameters) +static FError QspiSpiffsWriteRead(void) { - const char *pcTaskName = (char *) pvParameters; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); FError ret = FT_SUCCESS; char *string = "spiffs qspi write times"; static int i = 0; memset(fspiffs_wr_buf, 0, FSPIFFS_RW_BUF_SIZE); - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) - { - /* Print out the name of this task. */ - vPrintf(pcTaskName); - i++; - sprintf(fspiffs_wr_buf, "%s-%d", string, i); - vPrintf("Write to %s, str = %s\n", file_name, fspiffs_wr_buf); - - FSpiffsOpsWriteFile(file_name, fspiffs_wr_buf); - FSpiffsOpsReadFile(file_name); - - if (0 != strcmp(fspiffs_wr_buf, fspiffs_rd_buf)) - { - FSPIFFS_ERROR("Read and write data are not equal!!!!\nwrite data:%s ,read data:%s\n", fspiffs_wr_buf, fspiffs_rd_buf); - vTaskDelete(NULL); - } - else - { - printf("Successfully, read and write data are equal.\n\n"); - } - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); + /* Print out the name of this task. */ + FSPIFFS_INFO(xString); + i++; + sprintf(fspiffs_wr_buf, "%s-%d", string, i); + FSPIFFS_INFO("Write to %s, str = %s\n", file_name, fspiffs_wr_buf); + + FSpiffsOpsWriteFile(file_name, fspiffs_wr_buf); + FSpiffsOpsReadFile(file_name); + + if (0 != strcmp(fspiffs_wr_buf, fspiffs_rd_buf)) + { + FSPIFFS_ERROR("Read and write data are not equal!!!!\nwrite data:%s ,read data:%s\n", fspiffs_wr_buf, fspiffs_rd_buf); + return FSPIFFS_OPS_DATA_FAILED; } + else + { + printf("Successfully, read and write data are equal.\n\n"); + } + + return FSPIFFS_OPS_OK; } -static void prvOneShotTimerCallback(TimerHandle_t xTimer) + +static void FFreeRTOSQspiSpiffsWriteThenReadTask(void *pvParameters) { - /* Output a string to show the time at which the callback was executed. */ - vPrintf("One-shot timer callback executing, delete QspiSpiffs ReadTask and WriteTask.\r\n"); + FError ret = FT_SUCCESS; + int task_res = FSPIFFS_OPS_OK; + /* QspiSpiffs初始化 */ + ret = QspiSpiffsInit(); + if (ret != FT_SUCCESS) + { + task_res = FSPIFFS_OPS_INIT_FAILED; + FSPIFFS_ERROR("QspiSpiffsInit failed."); + goto task_exit; + } + /* QspiSpiffs写文件读文件 */ + ret = QspiSpiffsWriteRead(); + if (ret != FT_SUCCESS) + { + task_res = FSPIFFS_OPS_DATA_FAILED; + FSPIFFS_ERROR("QspiSpiffsWriteRead failed."); + goto task_exit; + } + /* 去初始化 */ FFreeRTOSQspiSpiffsDelete(); -} +task_exit: + xQueueSend(xQueue, &task_res, 0); + vTaskDelete(NULL); +} -BaseType_t FFreeRTOSQspiSpiffsCreate(u32 qspi_id) +int FFreeRTOSQspiSpiffsCreate(void) { BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - BaseType_t xTimerStarted = pdPASS; + int task_res = FSPIFFS_OPS_UNKNOWN_STATE; - xCountingSemaphore = xSemaphoreCreateCounting(READ_WRITE_TASK_NUM, 0); - if (xCountingSemaphore == NULL) + xQueue = xQueueCreate(1, sizeof(int)); /* 创建消息队列 */ + if (xQueue == NULL) { - printf("FFreeRTOSQspiSpiffsCreate xCountingSemaphore create failed.\r\n"); - return pdFAIL; - } + FSPIFFS_ERROR("xQueue create failed."); + goto exit; + } - taskENTER_CRITICAL(); /*进入临界区*/ - - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSQspiSpiffsInitTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSQspiSpiffsInitTask",/* 任务名字 */ + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSQspiSpiffsWriteThenReadTask, /* 任务入口函数 */ + (const char *)"FFreeRTOSQspiSpiffsWriteThenReadTask",/* 任务名字 */ (uint16_t)4096, /* 任务栈大小 */ - (void *)(uintptr)qspi_id,/* 任务入口函数参数 */ - (UBaseType_t)1, /* 任务的优先级 */ + NULL,/* 任务入口函数参数 */ + (UBaseType_t)QSPI_SPIFFS_WRITE_READ_TASK_PRIORITY, /* 任务的优先级 */ NULL); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSQspiSpiffsWriteReadTask, /* 任务入口函数 */ - (const char *)"FFreeRTOSQspiSpiffsWriteReadTask",/* 任务名字 */ - (uint16_t)4096, /* 任务栈大小 */ - (void *)xString,/* 任务入口函数参数 */ - (UBaseType_t)configMAX_PRIORITIES - 1, /* 任务的优先级 */ - (TaskHandle_t *)&qspi_rw_handle); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate("OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example does not use the timer id. */ - prvOneShotTimerCallback); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if (xOneShotTimer != NULL) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimerStarted = xTimerStart(xOneShotTimer, 0); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if (xTimerStarted != pdPASS) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed. \r\n"); - } - } - else + if (xReturn == pdFAIL) { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed. \r\n"); + FSPIFFS_ERROR("xTaskCreate FFreeRTOSQspiSpiffsWriteThenReadTask failed."); + goto exit; } - taskEXIT_CRITICAL(); - - return xReturn; -} - -static void FFreeRTOSQspiSpiffsDelete(void) -{ - BaseType_t xReturn = pdPASS; - FIOMuxDeInit();/*deinit iomux */ - FSpiffsDeInitialize(&instance); + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FSPIFFS_ERROR("xQueue receive timeout."); + goto exit; + } - if (qspi_rw_handle) +exit: + if (xQueue != NULL) { - vTaskDelete(qspi_rw_handle); - vPrintf("Delete FFreeRTOSQspiSpiffsWriteReadTask successfully.\r\n"); + vQueueDelete(xQueue); } - /* delete count sem */ - vSemaphoreDelete(xCountingSemaphore); - - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if (xReturn != pdPASS) + if (task_res != FSPIFFS_OPS_OK) { - vPrintf("OneShot Software Timer Delete failed.\r\n"); + printf("%s@%d: Qspi_spiffs write and read example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return task_res; } else { - vPrintf("OneShot Software Timer Delete successfully.\r\n"); + printf("%s@%d: Qspi_spiffs write and read example [success].\r\n", __func__, __LINE__); + return task_res; } +} +static void FFreeRTOSQspiSpiffsDelete(void) +{ + /*deinit iomux */ + FIOMuxDeInit(); + FSpiffsDeInitialize(&instance); + spiffs_inited = FALSE; + return; } diff --git a/example/storage/spim_spiffs/README.md b/example/storage/spim_spiffs/README.md index ef03e70f8c2e539cbc6c93ad9fcbbd25964c67b3..25b5bbafa253ecf34a6d9d69055dad1bde59adbb 100644 --- a/example/storage/spim_spiffs/README.md +++ b/example/storage/spim_spiffs/README.md @@ -106,16 +106,13 @@ bootelf -p 0x90100000 >描述输入输出情况,列出存在哪些输出,对应的输出是什么(建议附录相关现象图片)
-程序启动后,依次创建Init、Read、Write任务,创建单次模式软件定时器用于删除任务,Init任务会首先初始化并挂载spim flash的部分区域(可通过FSPIFFS_IF_FORMAT选择是否进行格式化操作),随后创建一个文件,然后释放信号量通知Read和Write任务开始执行; +首先初始化并挂载spim flash的部分区域(可通过FSPIFFS_IF_FORMAT选择是否进行格式化操作),随后创建一个文件,最后对文件进行读写,并检查读回的数据是否正确。 -- init完成,挂载文件系统完成,创建测试文件 -![init](./figs/init.png) +> spim_spiffs read_write + +![Alt text](./figs/result.png) -- 读写任务周期性执行,有两个读任务,一个写任务 -![wr](./figs/wr.png) -- 软件定时器触发,删除读写任务 -![delete](./figs/delete.png) ## 3. 如何解决问题 diff --git a/example/storage/spim_spiffs/figs/delete.png b/example/storage/spim_spiffs/figs/delete.png deleted file mode 100644 index fb0d47c2e106319953300b8e2da62e54a44513b2..0000000000000000000000000000000000000000 Binary files a/example/storage/spim_spiffs/figs/delete.png and /dev/null differ diff --git a/example/storage/spim_spiffs/figs/init.png b/example/storage/spim_spiffs/figs/init.png deleted file mode 100644 index 49fe3c33bf239f172ec58ed1cdf05b3631d3ab19..0000000000000000000000000000000000000000 Binary files a/example/storage/spim_spiffs/figs/init.png and /dev/null differ diff --git a/example/storage/spim_spiffs/figs/result.png b/example/storage/spim_spiffs/figs/result.png new file mode 100644 index 0000000000000000000000000000000000000000..e6af5bf6598f7bea1069961ff3df312e8dbdd288 Binary files /dev/null and b/example/storage/spim_spiffs/figs/result.png differ diff --git a/example/storage/spim_spiffs/figs/wr.png b/example/storage/spim_spiffs/figs/wr.png deleted file mode 100644 index 05b0cf56ceb81102d5b02ef24238cc6df1b51345..0000000000000000000000000000000000000000 Binary files a/example/storage/spim_spiffs/figs/wr.png and /dev/null differ diff --git a/example/storage/spim_spiffs/inc/spim_spiffs_example.h b/example/storage/spim_spiffs/inc/spim_spiffs_example.h index 44b464bb81912ada8b70c61250b37beefcb4d6b9..c948204aa0d4db133b6c0a85aeabbed27785dcb7 100644 --- a/example/storage/spim_spiffs/inc/spim_spiffs_example.h +++ b/example/storage/spim_spiffs/inc/spim_spiffs_example.h @@ -27,6 +27,8 @@ #define SPIM_SPIFFS_EXAMPLE_H /* spim spiffs read and write test */ -BaseType_t FFreeRTOSSpimSpiffsCreate(u32 spim_id); +int FFreeRTOSSpimSpiffsRunWR(void); + +void SpimSpiffsExampleEntry(void); #endif // ! \ No newline at end of file diff --git a/example/storage/spim_spiffs/main.c b/example/storage/spim_spiffs/main.c index e2d2c9908522e9910b8613d581a570ad5ec87f79..3e7ff2a53ab5ba31177921c88fadeab59c2ca76a 100644 --- a/example/storage/spim_spiffs/main.c +++ b/example/storage/spim_spiffs/main.c @@ -21,29 +21,35 @@ * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 liqiaozhong 2022/11/2 first commit + * 2.0 liyilun 2024/04/25 add no letter shell mode, adapt to auto test system */ -#include "shell.h" -#include "shell_port.h" #include +#include "FreeRTOS.h" +#include "task.h" #include "spim_spiffs_example.h" -#if defined(CONFIG_TARGET_E2000D)||defined(CONFIG_TARGET_E2000Q) -#define SPIM_TEST_ID FSPI2_ID -#elif defined(CONFIG_TARGET_PHYTIUMPI) -#define SPIM_TEST_ID FSPI0_ID + +#ifdef CONFIG_USE_LETTER_SHELL +#include "shell.h" +#include "shell_port.h" #endif + int main(void) { BaseType_t ret; - - ret = FFreeRTOSSpimSpiffsCreate(SPIM_TEST_ID); - if(ret != pdPASS) - goto FAIL_EXIT; - +#ifdef CONFIG_USE_LETTER_SHELL ret = LSUserShellTask() ; if(ret != pdPASS) goto FAIL_EXIT; +#else + ret = xTaskCreate((TaskFunction_t)SpimSpiffsExampleEntry, + (const char *)"SpimSpiffsExampleEntry", + (uint16_t)4096, + NULL, + (UBaseType_t)2, + NULL); +#endif vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ diff --git a/example/storage/spim_spiffs/makefile b/example/storage/spim_spiffs/makefile index 1cb0be19584339e4ec7b14a17beb92172c86e36a..feb2c855bca55bc060a7b6c78d5454845cce948e 100644 --- a/example/storage/spim_spiffs/makefile +++ b/example/storage/spim_spiffs/makefile @@ -22,8 +22,8 @@ USR_BOOT_DIR ?= /mnt/d/tftboot image: - $(MAKE) clean - $(MAKE) all -j + $(MAKE) -s clean + $(MAKE) -s all -j @cp ./$(IMAGE_OUT_NAME).elf $(USR_BOOT_DIR)/freertos.elf ifdef CONFIG_OUTPUT_BINARY @cp ./$(IMAGE_OUT_NAME).bin $(USR_BOOT_DIR)/freertos.bin diff --git a/example/system/posix/src/thread_demo.c b/example/storage/spim_spiffs/src/cmd_spiffs.c similarity index 33% rename from example/system/posix/src/thread_demo.c rename to example/storage/spim_spiffs/src/cmd_spiffs.c index f6010b196e28f575367b83cbd59dffebdee6f81c..dd58049e93626c12dc33c4ff75fade0f9029bc81 100644 --- a/example/system/posix/src/thread_demo.c +++ b/example/storage/spim_spiffs/src/cmd_spiffs.c @@ -11,68 +11,65 @@ * See the Phytium Public License for more details. * * - * FilePath: thread_demo.c - * Date: 2023-10-12 10:41:45 - * LastEditTime: 2023-10-12 10:41:45 - * Description: This file is for freertos posix thread function test + * FilePath: cmd_spim.c + * Date: 2024-04-22 14:53:42 + * LastEditTime: 2024-04-24 17:46:03 + * Description:  This file is for spim_spiffs example cmd catalogue * - * Modify History: - * Ver Who Date Changes - * ----- ------ -------- -------------------------------------- - * 1.0 wangxiaodong 2023/10/12 first commit + * Modify History: + * Ver   Who        Date         Changes + * ----- ------     --------    -------------------------------------- + * 1.0 liyilun 2024/4/22 first release */ - -#include -#include +/***************************** Include Files *********************************/ #include -#include -// #include -#include "FreeRTOS_POSIX/pthread.h" +#include +#include "sdkconfig.h" +#ifndef SDK_CONFIG_H__ + #warning "Please include sdkconfig.h" +#endif -/*要执行的线程*/ -void *test_thread(void *arg) -{ - int num = (unsigned long long)arg; /** sizeof(void*) == 8 and sizeof(int) == 4 (64 bits) */ +#include "FreeRTOS.h" +#include "task.h" +#include "spim_spiffs_example.h" - printf("This is test thread, arg is %d\n", num); - sleep(5); - /*退出线程*/ - pthread_exit(NULL); - return NULL; -} +#ifdef CONFIG_USE_LETTER_SHELL +#include "shell.h" +#include "strto.h" - -void CreateThreadDemoTasks(void) +static void SpimSpiffsCmdUsage() { - pthread_t thread; - void *thread_return; - int arg = 520; - int res; + printf("Usage:\r\n"); + printf("spim_spiffs read_write\r\n"); + printf("-- Demo read and write by spim_spiffs\r\n"); +} - printf("start create thread\n"); +static int SpimSpiffsCmdEntry(int argc, char *argv[]) +{ + int ret = 0; - /*创建线程,线程为test_thread函数*/ - res = pthread_create(&thread, NULL, test_thread, (void*)(arg)); - if(res != 0) + if (argc < 2) { - printf("create thread fail\n"); - exit(res); + SpimSpiffsCmdUsage(); + return -1; } - printf("create treads success\n"); - printf("waiting for threads to finish...\n"); - - /*等待线程终止*/ - res = pthread_join(thread, &thread_return); - if(res != 0) + if (!strcmp(argv[1], "read_write")) { - printf("thread exit fail\n"); - exit(res); + ret = FFreeRTOSSpimSpiffsRunWR(); } - printf("thread exit ok\n"); - + return ret; } +SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), spim_spiffs, SpimSpiffsCmdEntry, test freertos spim_spiffs); +#else +void SpimSpiffsExampleEntry(void) +{ + FFreeRTOSSpimSpiffsRunWR(); + printf("[test_end].\r\n"); + vTaskDelete(NULL); +} +#endif \ No newline at end of file diff --git a/example/storage/spim_spiffs/src/spim_spiffs_example.c b/example/storage/spim_spiffs/src/spim_spiffs_example.c index 19b1d687a56b288406b6e8b4b34cbda9797f50b3..8fef8f833d5ed566b524ede16cdf09222a1146bd 100644 --- a/example/storage/spim_spiffs/src/spim_spiffs_example.c +++ b/example/storage/spim_spiffs/src/spim_spiffs_example.c @@ -13,13 +13,14 @@ * * FilePath: spim_spiffs_example.c * Date: 2022-07-11 11:32:48 - * LastEditTime: 2022-07-11 11:32:48 + * LastEditTime: 2024-04-25 11:32:48 * Description: This file is for the spim_spiffs example functions. * * Modify History: * Ver Who Date Changes * ----- ------ -------- -------------------------------------- - * 1.0 liqiaozhong 2022/11/2 first commit + * 1.0 liqiaozhong 2022/11/2 first commit + * 2.0 liyilun 2024/04/25 add no letter shell mode, adapt to auto test system */ #include #include @@ -28,9 +29,7 @@ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "semphr.h" -#include "fio_mux.h" -#include "timers.h" +#include "queue.h" #include "spim_spiffs_example.h" #include "strto.h" #include "fassert.h" @@ -64,10 +63,11 @@ enum #define FSPIFFS_DEBUG(format, ...) FT_DEBUG_PRINT_D(FSPIFFS_DEBUG_TAG, format, ##__VA_ARGS__) /* spiffs start address and size */ -#define FSPIFFS_START_ADDR (0 * SZ_1M) +#define FSPIFFS_START_ADDR 0x0 #define FSPIFFS_USE_SIZE SZ_1M #define FSPIFFS_RW_BUF_SIZE 64 +#define WR_LOOP_TIMES 2 /* if format flash, TRUE is need format, it tasks some time */ #define FSPIFFS_IF_FORMAT TRUE @@ -76,32 +76,15 @@ enum static volatile u8 fspiffs_work_buf[FSPIFFS_LOG_PAGE_SIZE * 2] = {0}; static volatile u8 fspiffs_fds_buf[32 * 4] = {0}; static volatile u8 fspiffs_cache_buf[(FSPIFFS_LOG_PAGE_SIZE + 32) * 4] = {0}; -static u8 fspiffs_rw_buf[FSPIFFS_RW_BUF_SIZE] = {0}; +static QueueHandle_t xQueue = NULL; static FSpiffs instance; -static spiffs_config config; -static boolean spiffs_inited = FALSE; -const char *file_name = "test.txt"; -/************************** Constant Definitions *****************************/ - -/* The periods assigned to the one-shot timers. */ -#define ONE_SHOT_TIMER_PERIOD ( pdMS_TO_TICKS( 50000UL ) ) - -/* write and read task delay in milliseconds */ -#define TASK_DELAY_MS 3000UL - -/* write and read task number */ -#define READ_WRITE_TASK_NUM 2 -static xSemaphoreHandle xCountingSemaphore; - -static xTaskHandle spim_read1_handle; -static xTaskHandle spim_read2_handle; -static xTaskHandle spim_write_handle; -static TimerHandle_t xOneShotTimer; +/* The periods assigned to write and read. */ +#define WR_TIMER_PERIOD ( pdMS_TO_TICKS( 50000UL ) ) static void FFreeRTOSSpimSpiffsDelete(void); -static int FSpiffsOpsMount(boolean do_format) +static int FSpiffsOpsMount(boolean do_format, spiffs_config config) { int result = 0; @@ -116,7 +99,6 @@ static int FSpiffsOpsMount(boolean do_format) (u8_t *)fspiffs_cache_buf, sizeof(fspiffs_cache_buf), NULL); - /* try mount to get status of filesystem */ if ((SPIFFS_OK != result) && (SPIFFS_ERR_NOT_A_FS != result)) { @@ -125,7 +107,6 @@ static int FSpiffsOpsMount(boolean do_format) FSPIFFS_ERROR("mount spiffs failed: %d", result); return FSPIFFS_OPS_MOUNT_FAILED; } - /* must be unmounted prior to formatting */ SPIFFS_unmount(&instance.fs); @@ -137,7 +118,6 @@ static int FSpiffsOpsMount(boolean do_format) return FSPIFFS_OPS_FORMAT_FAILED; } } - /* real mount */ result = SPIFFS_mount(&instance.fs, &config, @@ -157,7 +137,6 @@ static int FSpiffsOpsMount(boolean do_format) vPrintf("mount spiffs success !!! \r\n"); instance.fs_ready = TRUE; } - return FSPIFFS_OPS_OK; } @@ -189,7 +168,6 @@ static int FSpiffsOpsListAll(void) cur_entry->obj_id, cur_entry->size); } - (void)SPIFFS_closedir(&dir); return ret; } @@ -295,13 +273,13 @@ int FSpiffsOpsWriteFile(const char *file_name, const char *str) /* flush all pending writes from cache to flash */ (void)SPIFFS_fflush(&instance.fs, fd); - vPrintf("write file %s with %d bytes success !!!\r\n", file_name, wr_len); + FSPIFFS_INFO("write file %s with %d bytes success !!!\r\n", file_name, wr_len); err_exit: (void)SPIFFS_close(&instance.fs, fd); return ret; } -int FSpiffsOpsReadFile(const char *file_name) +int FSpiffsOpsReadFile(const char *file_name, char *fspiffs_read_buf) { FASSERT((file_name) && (strlen(file_name) > 0)); int ret = FSPIFFS_OPS_OK; @@ -346,8 +324,6 @@ int FSpiffsOpsReadFile(const char *file_name) goto err_exit; } - memset(fspiffs_rw_buf, 0 , FSPIFFS_RW_BUF_SIZE); - /* seek to offset and start read */ if (0 > SPIFFS_lseek(&instance.fs, fd, 0, SPIFFS_SEEK_SET)) { @@ -359,7 +335,7 @@ int FSpiffsOpsReadFile(const char *file_name) /*vPrintf("read %s from position %ld\n", file_name, SPIFFS_tell(&instance.fs, fd));*/ s32_t read_len = min((s32_t)FSPIFFS_RW_BUF_SIZE, (s32_t)status.size); - s32_t read_bytes = SPIFFS_read(&instance.fs, fd, (void *)fspiffs_rw_buf, read_len); + s32_t read_bytes = SPIFFS_read(&instance.fs, fd, (void *)fspiffs_read_buf, read_len); if (read_bytes < 0) { FSPIFFS_ERROR("failed to read file %s errno %d", file_name, SPIFFS_errno(&instance.fs)); @@ -367,31 +343,18 @@ int FSpiffsOpsReadFile(const char *file_name) goto err_exit; } - vPrintf("read %s success, str = %s\n\n", file_name, fspiffs_rw_buf); + FSPIFFS_INFO("read %s success, str = %s\n", file_name, fspiffs_read_buf); err_exit : /* close file */ (void)SPIFFS_close(&instance.fs, fd); - return ret; } - -static void FFreeRTOSSpimSpiffsInitTask(void *pvParameters) +static int FFreeRTOSSpimSpiffsInit(const char *file_name) { - int result = 0; - - if (TRUE == spiffs_inited) - { - FSPIFFS_WARN("spiffs is already initialized"); - return; - } - - /* The spim_id to use is passed in via the parameter. - Cast this to a spim_id pointer. */ - u32 spim_id = (u32)(uintptr)pvParameters; - printf("spim_id: %d\n", spim_id); - + int result = FSPIFFS_OPS_OK; + static spiffs_config config; memset(&config, 0, sizeof(config)); config = *FSpiffsGetDefaultConfig(); config.phys_addr = FSPIFFS_START_ADDR; /* may use part of flash */ @@ -402,215 +365,109 @@ static void FFreeRTOSSpimSpiffsInitTask(void *pvParameters) instance.fs_size = FSPIFFS_USE_SIZE; result = FSpiffsInitialize(&instance, FSPIFFS_PORT_TO_FSPIM); - if (FSPIFFS_PORT_OK != result) + if (FSPIFFS_OPS_OK != result) { - FSPIFFS_ERROR("initialize spiffs failed"); - goto err_exit; + return FSPIFFS_OPS_INIT_FAILED; } - FSpiffsOpsMount(FSPIFFS_IF_FORMAT); - - FSpiffsOpsCreateFile(file_name); - - spiffs_inited = TRUE; - - FSpiffsOpsListAll(); + result = FSpiffsOpsMount(FSPIFFS_IF_FORMAT, config); + if(result != FSPIFFS_OPS_OK) + { + return result; - FSPIFFS_INFO("spiffs init success !!!\r\n"); + } - for (int i = 0; i < READ_WRITE_TASK_NUM; i++) + FSpiffsOpsCreateFile(file_name); + if(result != FSPIFFS_OPS_OK) { - xSemaphoreGive(xCountingSemaphore); + return result; } - -err_exit: - vTaskDelete(NULL); -} + FSpiffsOpsListAll(); + FSPIFFS_INFO("spiffs init success !!!\r\n"); + return result; -static void FFreeRTOSSpimSpiffsReadTask(void *pvParameters) -{ - const char *pcTaskName = (char *) pvParameters; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FT_SUCCESS; - - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - /* As per most tasks, this task is implemented in an infinite loop. */ - for( ;; ) - { - /* Print out the name of this task. */ - vPrintf( pcTaskName ); - - FSpiffsOpsReadFile(file_name); - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); - } } - -static void FFreeRTOSSpimSpiffsWriteTask(void *pvParameters) +static void FFreeRTOSSpimSpiffsWRTask() { - const char *pcTaskName = "FFreeRTOSSpimSpiffsWriteTask is running\r\n"; - const TickType_t xDelay = pdMS_TO_TICKS(TASK_DELAY_MS); - FError ret = FT_SUCCESS; - char *string = "spiffs spim write"; - static char string_out[FSPIFFS_RW_BUF_SIZE] = {0}; - - static int i = 0; - - xSemaphoreTake(xCountingSemaphore, portMAX_DELAY); - - /* As per most tasks, this task is implemented in an infinite loop. */ - for (;;) + const char *file_name = "test.txt"; + int ret = FSPIFFS_OPS_OK; + u8 fspiffs_write_buf[FSPIFFS_RW_BUF_SIZE] = {0}; + u8 fspiffs_read_buf[FSPIFFS_RW_BUF_SIZE] = {0}; + char *string = "hello,freertos. spiffs spim write and read test"; + int i = 0; + ret = FFreeRTOSSpimSpiffsInit(file_name); + if(ret != FSPIFFS_OPS_OK) { - /* Print out the name of this task. */ - vPrintf( pcTaskName ); - i++; - sprintf(string_out, "%s-%d", string, i); - vPrintf( "write to %s, str = %s\n", file_name, string_out); - FSpiffsOpsWriteFile(file_name, string_out); - - /* Delay for a period. This time a call to vTaskDelay() is used which - places the task into the Blocked state until the delay period has - expired. The parameter takes a time specified in 'ticks', and the - pdMS_TO_TICKS() macro is used (where the xDelay constant is - declared) to convert TASK_DELAY_MS milliseconds into an equivalent time in - ticks. */ - vTaskDelay(xDelay); - } -} - -static void prvOneShotTimerCallback( TimerHandle_t xTimer ) -{ - /* Output a string to show the time at which the callback was executed. */ - vPrintf( "One-shot timer callback executing, delete SpimSpiffs ReadTask and WriteTask.\r\n" ); - - FFreeRTOSSpimSpiffsDelete(); -} + FSPIFFS_ERROR("Spiffs init fail."); + goto task_ret; + } + /* write and read */ + for(i = 0; i < WR_LOOP_TIMES; i++) + { + memset(fspiffs_read_buf, 0, FSPIFFS_RW_BUF_SIZE); + memset(fspiffs_write_buf, 0, FSPIFFS_RW_BUF_SIZE); + sprintf(fspiffs_write_buf, "%s-%d", string, i); + FSPIFFS_INFO( "write to %s, str = %s\n", file_name, fspiffs_write_buf); -BaseType_t FFreeRTOSSpimSpiffsCreate(u32 spim_id)/* 主要任务函数 */ -{ - BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */ - BaseType_t xTimerStarted = pdPASS; - - xCountingSemaphore = xSemaphoreCreateCounting(READ_WRITE_TASK_NUM, 0); - if (xCountingSemaphore == NULL) - { - printf("FFreeRTOSSpimSpiffsCreate xCountingSemaphore create failed.\r\n" ); - return pdFAIL; + ret = FSpiffsOpsWriteFile(file_name, fspiffs_write_buf); + if(ret != FSPIFFS_OPS_OK) + { + FSPIFFS_ERROR("Write file fail."); + goto task_ret; + } + /*read after write*/ + ret = FSpiffsOpsReadFile(file_name, fspiffs_read_buf); + if(ret != FSPIFFS_OPS_OK) + { + FSPIFFS_ERROR("Read file fail."); + goto task_ret; + } + /*compare write data and read data*/ + if (0 != memcmp(fspiffs_read_buf, fspiffs_write_buf, FSPIFFS_RW_BUF_SIZE)) + { + FSPIFFS_ERROR("times %d: spim spiffs write and read failed.\r\n\n",i); + ret = FSPIFFS_OPS_READ_FILE_FAILED; + goto task_ret; + } + else + { + printf("times %d: spim spiffs write and read pass.\r\n\n",i); + } } + ret = FSPIFFS_OPS_OK; +task_ret: + FSpiffsDeInitialize(&instance); + xQueueSend(xQueue,&ret,0); + vTaskDelete(NULL); - char *xString1 = "FFreeRTOSSpimSpiffsReadTask1 is running\r\n"; - char *xString2 = "FFreeRTOSSpimSpiffsReadTask2 is running\r\n"; - - taskENTER_CRITICAL(); /* 进入临界区 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSpimSpiffsInitTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSSpimSpiffsInitTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )(uintptr)spim_id,/* 任务入口函数参数 */ - (UBaseType_t )1, /* 任务的优先级 */ - NULL); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSpimSpiffsReadTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSSpimSpiffsReadTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )xString2,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-2, /* 任务的优先级 */ - (TaskHandle_t* )&spim_read2_handle); /* 任务控制 */ - - xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSpimSpiffsWriteTask, /* 任务入口函数 */ - (const char* )"FFreeRTOSSpimSpiffsWriteTask",/* 任务名字 */ - (uint16_t )4096, /* 任务栈大小 */ - (void* )NULL,/* 任务入口函数参数 */ - (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ - (TaskHandle_t* )&spim_write_handle); /* 任务控制 */ - - /* Create the one shot software timer, storing the handle to the created - software timer in xOneShotTimer. */ - xOneShotTimer = xTimerCreate( "OneShot Software Timer", /* Text name for the software timer - not used by FreeRTOS. */ - ONE_SHOT_TIMER_PERIOD, /* The software timer's period in ticks. */ - pdFALSE, /* Setting uxAutoRealod to pdFALSE creates a one-shot software timer. */ - 0, /* This example does not use the timer id. */ - prvOneShotTimerCallback ); /* The callback function to be used by the software timer being created. */ - - /* Check the timers were created. */ - if( xOneShotTimer != NULL ) - { - /* Start the software timers, using a block time of 0 (no block time). - The scheduler has not been started yet so any block time specified here - would be ignored anyway. */ - xTimerStarted = xTimerStart( xOneShotTimer, 0 ); - - /* The implementation of xTimerStart() uses the timer command queue, and - xTimerStart() will fail if the timer command queue gets full. The timer - service task does not get created until the scheduler is started, so all - commands sent to the command queue will stay in the queue until after - the scheduler has been started. Check both calls to xTimerStart() - passed. */ - if( xTimerStarted != pdPASS) - { - vPrintf("CreateSoftwareTimerTasks xTimerStart failed \r\n"); - } - } - else - { - vPrintf("CreateSoftwareTimerTasks xTimerCreate failed \r\n"); - } - - taskEXIT_CRITICAL(); - - return xReturn; } - -static void FFreeRTOSSpimSpiffsDelete(void) +int FFreeRTOSSpimSpiffsRunWR(void) { - BaseType_t xReturn = pdPASS; - - FSpiffsDeInitialize(&instance); - - if(spim_read1_handle) + BaseType_t xReturn = pdPASS; + int task_ret; + xQueue = xQueueCreate(1,sizeof(int)); + xReturn = xTaskCreate((TaskFunction_t )FFreeRTOSSpimSpiffsWRTask, /* 任务入口函数 */ + (const char* )"FFreeRTOSSpimSpiffsWRTask",/* 任务名字 */ + (uint16_t )4096, /* 任务栈大小 */ + (void* )NULL,/* 任务入口函数参数 */ + (UBaseType_t )configMAX_PRIORITIES-1, /* 任务的优先级 */ + NULL); /* 任务控制 */ + + xReturn = xQueueReceive(xQueue, &task_ret, WR_TIMER_PERIOD); + FASSERT_MSG(pdPASS == xReturn, "xQueue Receive failed.\r\n"); + vQueueDelete(xQueue); + if(task_ret != FSPIFFS_OPS_OK) { - vTaskDelete(spim_read1_handle); - vPrintf("Delete FFreeRTOSSpimSpiffsReadTask1 success\r\n"); + printf("%s@%d: Spim_spiffs wr example [failure].\r\n", __func__, __LINE__); } - - if(spim_read2_handle) - { - vTaskDelete(spim_read2_handle); - vPrintf("Delete FFreeRTOSSpimSpiffsReadTask2 success\r\n"); - } - - if(spim_write_handle) + else { - vTaskDelete(spim_write_handle); - vPrintf("Delete FFreeRTOSSpimSpiffsWriteTask success\r\n"); + printf("%s@%d: Spim_spiffs wr example [success].\r\n", __func__, __LINE__); } - - /* delete count sem */ - vSemaphoreDelete(xCountingSemaphore); - - /* delete timer */ - xReturn = xTimerDelete(xOneShotTimer, 0); - if(xReturn != pdPASS) - { - vPrintf("OneShot Software Timer Delete failed.\r\n"); - } - else - { - vPrintf("OneShot Software Timer Delete success.\r\n"); - } - -} - - + return task_ret; +} \ No newline at end of file diff --git a/example/system/amp/openamp/device_core/main.c b/example/system/amp/openamp/device_core/main.c index a769ae0caa4e807d95d8e148dbe8bd0fb683f2fc..db4b6a262141cd29c9cb3c995107b05752cb0eb1 100644 --- a/example/system/amp/openamp/device_core/main.c +++ b/example/system/amp/openamp/device_core/main.c @@ -13,7 +13,7 @@ * * FilePath: main.c * Created Date: 2022-02-25 13:25:14 - * Last Modified: 2024-03-05 11:30:19 + * Last Modified: 2024-05-06 17:56:58 * Description: This file is for main * * Modify History: @@ -45,7 +45,7 @@ int main(void) ret = rpmsg_listening_func(); if(ret != pdPASS) goto FAIL_EXIT; - OPENAMP_MAIN_DEBUG_I("Creat task OK!"); + OPENAMP_MAIN_DEBUG_I("Create task OK!"); vTaskStartScheduler(); /* 启动任务,开启调度 */ while (1); /* 正常不会执行到这里 */ diff --git a/example/system/amp/openamp/device_core/makefile b/example/system/amp/openamp/device_core/makefile index 04b1060e22c139d60738b9621eae223dbcb70073..24c24cea2575f8d36a6e240210d1c07b942ef61d 100644 --- a/example/system/amp/openamp/device_core/makefile +++ b/example/system/amp/openamp/device_core/makefile @@ -20,8 +20,8 @@ USER_BOOT_IMAGE ?= openamp_device_core # 完成编译 image: - $(MAKE) clean - $(MAKE) all -j + $(MAKE) -s clean + $(MAKE) -s all -j @cp ./$(IMAGE_OUT_NAME).elf $(USR_BOOT_DIR)/$(USER_BOOT_IMAGE).elf ifdef CONFIG_OUTPUT_BINARY @cp ./$(IMAGE_OUT_NAME).bin $(USR_BOOT_DIR)/$(USER_BOOT_IMAGE).bin diff --git a/example/system/amp/openamp/driver_core/makefile b/example/system/amp/openamp/driver_core/makefile index 34e62543bbf99f9062c784c41dc7e2539c2d8186..89563382ec15e602ed913c8459b8539a021594b0 100644 --- a/example/system/amp/openamp/driver_core/makefile +++ b/example/system/amp/openamp/driver_core/makefile @@ -20,8 +20,8 @@ USER_BOOT_IMAGE ?= openamp_driver_core # 完成编译 image: - $(MAKE) clean - $(MAKE) all -j + $(MAKE) -s clean + $(MAKE) -s all -j @cp ./$(IMAGE_OUT_NAME).elf $(USR_BOOT_DIR)/$(USER_BOOT_IMAGE).elf ifdef CONFIG_OUTPUT_BINARY @cp ./$(IMAGE_OUT_NAME).bin $(USR_BOOT_DIR)/$(USER_BOOT_IMAGE).bin diff --git a/example/system/amp/openamp/makefile b/example/system/amp/openamp/makefile index b4ee68b15dee2edb7e07497a86c341f459a89e5f..97291dacd62898e630bc13c963adc00ba9edb37e 100644 --- a/example/system/amp/openamp/makefile +++ b/example/system/amp/openamp/makefile @@ -3,10 +3,10 @@ .PHONY: all clean boot menuconfig_driver_core menuconfig_device_core clean_driver_core: - $(MAKE) -C ./driver_core clean + $(MAKE) -s -C ./driver_core clean clean_device_core: - $(MAKE) -C ./device_core clean + $(MAKE) -s -C ./device_core clean clean: clean_driver_core clean_device_core @@ -57,8 +57,8 @@ menuconfig_device_core: $(MAKE) -C ./device_core menuconfig image: - $(MAKE) -C ./driver_core image - $(MAKE) -C ./device_core image + $(MAKE) -s -C ./driver_core image + $(MAKE) -s -C ./device_core image backupconfig: $(MAKE) -C ./driver_core backup_kconfig diff --git a/example/system/atomic/README.md b/example/system/atomic/README.md index ba36f78c5fd3059e42fcdb578c731d7644a14711..5feb83b94cb8ef50345fce70aa65f376fb0a8b0f 100644 --- a/example/system/atomic/README.md +++ b/example/system/atomic/README.md @@ -7,6 +7,20 @@ GCC 4.1.2版本之后,提供了许多原子函数(Atomic Built-in Functions),这些函数主要用于实现线程安全的共享内存访问,可以保证共享变量的原子性、顺序性和正确性。 原子函数在多线程或多进程编程中广泛应用,特别是在实现同步机制、锁和条件变量等方面具有重要作用。 +本例程分别测试了以下原子操作: + +| **原子操作** | +| :----------: | +| FATOMIC_ADD 加法 | +| FATOMIC_INC 自加| +| FATOMIC_SUB 减法| +| FATOMIC_DEC 自减| +| FATOMIC_OR 或计算| +| FATOMIC_AND 与计算| +| FATOMIC_CAS_BOOL 比较运算(返回布尔类型)| +| FATOMIC_CAS_VAL 比较运算(返回数据类型)| +| FATOMIC_LOCK 原子锁| +| FATOMIC_UNLOCK 原子锁释放| ## 2. 如何使用例程 @@ -14,7 +28,7 @@ GCC 4.1.2版本之后,提供了许多原子函数(Atomic Built-in Functions 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -83,9 +97,5 @@ bootelf -p 0x90100000 $ atomic cre ``` -- 删除原子操作测试任务 -``` -$ atomic del -``` - +![atomic_test](./figs/atomic_test.png) ## 3. 如何解决问题 diff --git a/example/system/atomic/figs/atomic_test.png b/example/system/atomic/figs/atomic_test.png new file mode 100644 index 0000000000000000000000000000000000000000..a569b22765405cf50eb32ed197f202450d5fb7fc Binary files /dev/null and b/example/system/atomic/figs/atomic_test.png differ diff --git a/example/system/atomic/inc/atomic_example.h b/example/system/atomic/inc/atomic_example.h index f430b3a6da2c9df0941e892884ae433f7e25d2ca..162f45951f2aaa1cfe9bf8482d7c86855189d5c7 100644 --- a/example/system/atomic/inc/atomic_example.h +++ b/example/system/atomic/inc/atomic_example.h @@ -25,16 +25,13 @@ #ifndef ATOMIC_EXAMPLE_H #define ATOMIC_EXAMPLE_H - +#include "FreeRTOS.h" #ifdef __cplusplus extern "C" { #endif -/* atomic task */ -void CreateAtomicTasks(void); -void DeleteAtomicTasks(void); - +BaseType_t FFreeRTOSAtomicTaskCreate(void); #ifdef __cplusplus } #endif diff --git a/example/system/atomic/main.c b/example/system/atomic/main.c index 0da4caf9efd25eaa401935bf312059e09bae3aee..507bd133cfb859594640e6056f371b046577e2f9 100644 --- a/example/system/atomic/main.c +++ b/example/system/atomic/main.c @@ -24,18 +24,39 @@ #include #include #include "FreeRTOS.h" -#include "task.h" -#include "ftypes.h" +#include "sdkconfig.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include "sdkconfig.h" +#else +#include "task.h" +#include "atomic_example.h" +#define ATOMIC_EXAMPLE_TASK_PRIORITY 2 +void AtomicExampleTaskEntry() +{ + FFreeRTOSAtomicTaskCreate(); + + printf("[test_end]\r\n"); + + vTaskDelete(NULL); +} +#endif int main() { - printf("Atomic test func, FT Date: %s, Time: %s\n", __DATE__, __TIME__); BaseType_t xReturn = pdPASS; +#ifdef CONFIG_USE_LETTER_SHELL xReturn = LSUserShellTask(); +#else + xReturn = xTaskCreate((TaskFunction_t)AtomicExampleTaskEntry, /* 任务入口函数 */ + (const char *)"AtomicExampleTaskEntry", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)ATOMIC_EXAMPLE_TASK_PRIORITY, /* 任务的优先级 */ + NULL); +#endif if (xReturn != pdPASS) { goto FAIL_EXIT; diff --git a/example/system/atomic/src/atomic_example.c b/example/system/atomic/src/atomic_example.c index 85aaf20049ab336ef5b8645971dbaa28b083b30d..331a61eda09e595bb332b6c7c5f16224c34f6239 100644 --- a/example/system/atomic/src/atomic_example.c +++ b/example/system/atomic/src/atomic_example.c @@ -20,106 +20,189 @@ * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 wangxiaodong 2023/06/23 first release + * 1.1 zhangyan 2024/4/29 add no letter shell mode, adapt to auto-test system */ #include #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" +#include "queue.h" #include "fatomic.h" -#include "fassert.h" #include "fkernel.h" -static xTaskHandle xtask_handle; - +#define TIMER_OUT (pdMS_TO_TICKS(1000UL)) #define TASK_STACK_SIZE 1024 +#define ATOMIC_TEST_TASK_PRIORITY 3 +enum +{ + ATOMIC_TEST_SUCCESS = 0, + ATOMIC_TEST_UNKNOWN = 1, + ATOMIC_TEST_FAILURE = 2, +}; +static QueueHandle_t xQueue = NULL; -void FAtomicExample(void *pvParameters) +void FAtomicExampleTask(void *pvParameters) { + int task_res = ATOMIC_TEST_SUCCESS; int ret; int i = 0; u32 count = 0; u32 times = 0; - for (;;) - { - i = 0; - count = 0; - while (i++ < 10) - { - ret = FATOMIC_ADD(count, 1); - } - FASSERT_MSG(count == 10, "FATOMIC_ADD error\r\n"); - - i = 0; - while (i++ < 10) - { - ret = FATOMIC_INC(count); - } - FASSERT_MSG(count == 20, "FATOMIC_INC error\r\n"); - - i = 0; - while (i++ < 10) - { - ret = FATOMIC_SUB(count, 1); - } - FASSERT_MSG(count == 10, "FATOMIC_SUB error\r\n"); - - i = 0; - while (i++ < 10) - { - ret = FATOMIC_DEC(count); - } - FASSERT_MSG(count == 0, "FATOMIC_DEC error\r\n"); - - i = 0; - count = 0; - while (i++ < 16) - { - ret = FATOMIC_OR(count, BIT(i-1)); - } - FASSERT_MSG(count == 0xFFFF, "FATOMIC_OR error\r\n"); - - i = 0; - count = 0xFFFF; - while (i++ < 16) - { - ret = FATOMIC_AND(count, ~BIT(i-1)); - } - FASSERT_MSG(count == 0, "FATOMIC_AND error\r\n"); - - FATOMIC_CAS_BOOL(count, 0, 1); - FASSERT_MSG(count == 1, "FATOMIC_CAS_BOOL error\r\n"); - - FATOMIC_CAS_VAL(count, 0xFF, 0); - FASSERT_MSG(count == 1, "FATOMIC_CAS_VAL error\r\n"); - - FATOMIC_LOCK(count, 1); - FASSERT_MSG(count == 1, "FATOMIC_LOCK error\r\n"); - - FATOMIC_UNLOCK(count); - FASSERT_MSG(count == 0, "FATOMIC_UNLOCK error\r\n"); - - printf("Atomic example test success, times = %d!!! \r\n", times++); - - vTaskDelay(1000); + + while (i++ < 10) + { + ret = FATOMIC_ADD(count, 1); + } + if (count != 10) + { + printf("FATOMIC_ADD error\r\n"); + task_res = ATOMIC_TEST_FAILURE; + goto task_exit; + } + + i = 0; + while (i++ < 10) + { + ret = FATOMIC_INC(count); + } + if (count != 20) + { + printf("FATOMIC_INC error\r\n"); + task_res = ATOMIC_TEST_FAILURE; + goto task_exit; } -} + i = 0; + while (i++ < 10) + { + ret = FATOMIC_SUB(count, 1); + } + if (count != 10) + { + printf("FATOMIC_SUB error\r\n"); + task_res = ATOMIC_TEST_FAILURE; + goto task_exit; + } + i = 0; + while (i++ < 10) + { + ret = FATOMIC_DEC(count); + } + if (count != 0) + { + printf("FATOMIC_DEC error\r\n"); + task_res = ATOMIC_TEST_FAILURE; + goto task_exit; + } -void CreateAtomicTasks(void) -{ - printf("Create Atomic Task \r\n"); - xTaskCreate(FAtomicExample, "AtomicPeriodic", TASK_STACK_SIZE, NULL, 6, &xtask_handle); + i = 0; + count = 0; + while (i++ < 16) + { + ret = FATOMIC_OR(count, BIT(i-1)); + } + if (count != 0xFFFF) + { + printf("FATOMIC_OR error\r\n"); + task_res = ATOMIC_TEST_FAILURE; + goto task_exit; + } + + i = 0; + count = 0xFFFF; + while (i++ < 16) + { + ret = FATOMIC_AND(count, ~BIT(i-1)); + } + if (count != 0) + { + printf("FATOMIC_AND error\r\n"); + task_res = ATOMIC_TEST_FAILURE; + goto task_exit; + } + + FATOMIC_CAS_BOOL(count, 0, 1); + if (count != 1) + { + printf("FATOMIC_CAS_BOOL error\r\n"); + task_res = ATOMIC_TEST_FAILURE; + goto task_exit; + } + + FATOMIC_CAS_VAL(count, 0xFF, 0); + if (count != 1) + { + printf("FATOMIC_CAS_VAL error\r\n"); + task_res = ATOMIC_TEST_FAILURE; + goto task_exit; + } + + FATOMIC_LOCK(count, 1); + if (count != 1) + { + printf("FATOMIC_LOCK error\r\n"); + task_res = ATOMIC_TEST_FAILURE; + goto task_exit; + } + + FATOMIC_UNLOCK(count); + if (count != 0) + { + printf("FATOMIC_UNLOCK error\r\n"); + task_res = ATOMIC_TEST_FAILURE; + goto task_exit; + } +task_exit: + xQueueSend(xQueue, &task_res, 0); + + vTaskDelete(NULL); } -void DeleteAtomicTasks(void) +BaseType_t FFreeRTOSAtomicTaskCreate(void) { - if (xtask_handle) + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = ATOMIC_TEST_UNKNOWN; + + xQueue = xQueueCreate(1, sizeof(int)); + if (xQueue == NULL) + { + printf("xQueue create failed.\r\n"); + goto exit; + } + + xReturn = xTaskCreate((TaskFunction_t)FAtomicExampleTask, /* 任务入口函数 */ + (const char *)"FAtomicExampleTask", /* 任务名字 */ + (uint16_t)TASK_STACK_SIZE, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)ATOMIC_TEST_TASK_PRIORITY, /* 任务的优先级 */ + NULL); + if (xReturn == pdFAIL) + { + printf("xTaskCreate FAtomicExampleTask failed."); + goto exit; + } + + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + printf("xQueue receive timeout.\r\n"); + goto exit; + } + +exit: + vQueueDelete(xQueue); + if (task_res != ATOMIC_TEST_SUCCESS) + { + printf("%s@%d: Atomic test example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return pdFAIL; + } + else { - vTaskDelete(xtask_handle); - printf("AtomicPeriodic deletion \r\n"); + printf("%s@%d: Atomic test indirect example [success].\r\n", __func__, __LINE__); + return pdTRUE; } } \ No newline at end of file diff --git a/example/system/atomic/src/atomic_example_cmd.c b/example/system/atomic/src/atomic_example_cmd.c index b199618f2a0ded21e264075555ecd5f19ecc7cbd..938edea82c5a6a5bc4f92415939a4095410587be 100644 --- a/example/system/atomic/src/atomic_example_cmd.c +++ b/example/system/atomic/src/atomic_example_cmd.c @@ -20,26 +20,25 @@ * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2023/06/25 first commit + * 1.1 zhangyan 2024/4/29 add no letter shell mode, adapt to auto-test system */ #include #include -#include "shell.h" #include "atomic_example.h" +#include "sdkconfig.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "shell.h" static void CreateAtomicCmdUsage(void) { printf("Usage:\r\n"); printf(" atomic cre \r\n"); printf(" -- Create atomic test task now.\r\n"); - printf(" atomic del \r\n"); - printf(" -- Del atomic test task now.\r\n"); } int CreateAtomicCmd(int argc, char *argv[]) { - static int create_flg = 0; /* 1 is tasks has been created*/ - if (argc < 2) { CreateAtomicCmdUsage(); @@ -48,27 +47,7 @@ int CreateAtomicCmd(int argc, char *argv[]) if (!strcmp(argv[1], "cre")) { - if (create_flg == 0) - { - CreateAtomicTasks(); - create_flg = 1; - } - else - { - printf("Please use atomic del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "del")) - { - if (create_flg == 1) - { - DeleteAtomicTasks(); - create_flg = 0; - } - else - { - printf("Please use atomic cre cmd first. \r\n"); - } + FFreeRTOSAtomicTaskCreate(); } else { @@ -79,5 +58,4 @@ int CreateAtomicCmd(int argc, char *argv[]) } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), atomic, CreateAtomicCmd, atomic task test); - - +#endif diff --git a/example/system/exception_debug/README.md b/example/system/exception_debug/README.md index 7e92fe3964f889a3da0f0b8a8a47e411566077f5..d5d2fbf07b04ca59de8771da5cd15613d824b953 100644 --- a/example/system/exception_debug/README.md +++ b/example/system/exception_debug/README.md @@ -21,7 +21,7 @@ EXCEPTION_ACCESS_VIOLATION:Memory access violation,越界访问地址空间 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 diff --git a/example/system/nested_interrupt/README.md b/example/system/nested_interrupt/README.md index c97b17bd2e10e64e290251b686f45afea3a9e188..e41b34f92a38e865779584ada1965de6fa8fc543 100644 --- a/example/system/nested_interrupt/README.md +++ b/example/system/nested_interrupt/README.md @@ -2,14 +2,18 @@ ## 1. 例程介绍 -本例程示范了freertos环境下中断嵌套的使用方法 +中断嵌套测试例程 (nested_interrupt.c) +- 将两个不同优先级的中断绑定至当前CPU(low-priority-intr和high-priority-intr),并设定各自的中断服务函数 +- 循环5次触发low-priority-intr,在low-priority-intr的中断服务函数中,触发high-priority-intr中断,并等待CPU执行high-priority-intr的中断服务函数 +- 可以观测到,在执行low-priority-intr的中断服务函数的时候,CPU可以响应high-priority-intr中断,并执行high-priority-intr的中断服务函数 +- 根据flag值,以及val_low和val_high最终计算值,可判断例程测试成功 ## 2. 如何使用例程 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -100,10 +104,9 @@ bootelf -p 0x90100000 ### 2.4 输出与实验现象 -- 系统进入后,输入 ``nest``查看指令说明 - -- 输入 ``nest cre``,启动中断嵌套测试 -- 输入 ``nest del``,删除中断嵌套测试 +``` +$ nest cre +``` ![nested](./figs/nest_intr.png) diff --git a/example/system/nested_interrupt/figs/nest_intr.png b/example/system/nested_interrupt/figs/nest_intr.png index 9070c31bd1dced6c323fd590e4026ff700595e17..2fc9dc4c447f38ff64dad86df3abaa9a351a15fe 100644 Binary files a/example/system/nested_interrupt/figs/nest_intr.png and b/example/system/nested_interrupt/figs/nest_intr.png differ diff --git a/example/system/nested_interrupt/inc/nested_interrupt.h b/example/system/nested_interrupt/inc/nested_interrupt.h index 5cff44acce93fa6f097a54edd64bc6f0262cc414..270eaba96daba4a5ea6d5a1a05410ae0322b15aa 100644 --- a/example/system/nested_interrupt/inc/nested_interrupt.h +++ b/example/system/nested_interrupt/inc/nested_interrupt.h @@ -20,20 +20,19 @@ * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2023/02/25 first commit + * 1.1 zhangyan 2024/4/29 add no letter shell mode, adapt to auto-test system */ - #ifndef NESTED_INTERRUPT_H #define NESTED_INTERRUPT_H +#include"FreeRTOS.h" #ifdef __cplusplus extern "C" { #endif -/* interrupt task */ -void CreateNestedTasks(void); -void DeleteNestedTasks(void); +BaseType_t FFreeRTOSNestedIntrTaskCreate(void); #ifdef __cplusplus } diff --git a/example/system/nested_interrupt/main.c b/example/system/nested_interrupt/main.c index 7b0ddfc5cd1b2a0ddb64a34ffb255e4e6513c90c..4043d48880249f106951bb7bb7a3e3cb057af445 100644 --- a/example/system/nested_interrupt/main.c +++ b/example/system/nested_interrupt/main.c @@ -20,26 +20,56 @@ * Ver   Who        Date         Changes * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2023/2/23 first release + * 1.1 zhangyan 2024/4/29 add no letter shell mode, adapt to auto-test system */ +#include +#include "sdkconfig.h" +#include "FreeRTOS.h" +#include "task.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" -#include +#else +#include "task.h" +#include "nested_interrupt.h" +#define NESTED_EXAMPLE_TASK_PRIORITY 2 + +void NestedExampleTaskEntry() +{ + FFreeRTOSNestedIntrTaskCreate(); -int main(void) + printf("[test_end]\r\n"); + + vTaskDelete(NULL); +} +#endif + +int main() { - BaseType_t ret; - - ret = LSUserShellTask() ; - if (ret != pdPASS) + BaseType_t xReturn = pdPASS; + +#ifdef CONFIG_USE_LETTER_SHELL + xReturn = LSUserShellTask(); +#else + xReturn = xTaskCreate((TaskFunction_t)NestedExampleTaskEntry, /* 任务入口函数 */ + (const char *)"NestedExampleTaskEntry", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)NESTED_EXAMPLE_TASK_PRIORITY, /* 任务的优先级 */ + NULL); +#endif + if (xReturn != pdPASS) { goto FAIL_EXIT; } vTaskStartScheduler(); /* 启动任务,开启调度 */ + while (1); /* 正常不会执行到这里 */ FAIL_EXIT: - printf("Failed 0x%x. \r\n", ret); + printf("Failed,the xReturn value is 0x%x. \r\n", xReturn); return 0; } diff --git a/example/system/nested_interrupt/src/nested_cmd.c b/example/system/nested_interrupt/src/nested_cmd.c index eb4d343b4509a0bdd31cfc11d1f1f38142058442..8743a569074764006d41cef276403564fc34be92 100644 --- a/example/system/nested_interrupt/src/nested_cmd.c +++ b/example/system/nested_interrupt/src/nested_cmd.c @@ -20,32 +20,24 @@ * Ver Who Date Changes * ----- ------ -------- -------------------------------------- * 1.0 wangxiaodong 2023/02/25 first commit + * 1.1 zhangyan 2024/4/29 add no letter shell mode, adapt to auto-test system */ -#include "shell.h" #include #include #include "nested_interrupt.h" +#include "sdkconfig.h" -typedef enum -{ - NEST_TASK_INDEX = 0, - - INTR_TASK_LENGTH -} FreeRtosNestIntrSelect; - +#ifdef CONFIG_USE_LETTER_SHELL +#include "shell.h" static void CreateNestIntrCmdUsage(void) { printf("Usage:\r\n"); printf(" nest cre \r\n"); printf(" -- Create nest tasks now.\r\n"); - printf(" nest del \r\n"); - printf(" -- Del nest tasks now.\r\n"); } int CreateNestIntrCmd(int argc, char *argv[]) { - static int create_flg[INTR_TASK_LENGTH] = {0}; /* 1 is tasks has been created*/ - if (argc < 2) { CreateNestIntrCmdUsage(); @@ -54,27 +46,7 @@ int CreateNestIntrCmd(int argc, char *argv[]) if (!strcmp(argv[1], "cre")) { - if (create_flg[NEST_TASK_INDEX] == 0) - { - CreateNestedTasks(); - create_flg[NEST_TASK_INDEX] = 1; - } - else - { - printf("Please use nest del cmd first. \r\n"); - } - } - else if (!strcmp(argv[1], "del")) - { - if (create_flg[NEST_TASK_INDEX] == 1) - { - DeleteNestedTasks(); - create_flg[NEST_TASK_INDEX] = 0; - } - else - { - printf("Please use nest cre cmd first. \r\n"); - } + FFreeRTOSNestedIntrTaskCreate(); } else { @@ -85,5 +57,6 @@ int CreateNestIntrCmd(int argc, char *argv[]) } SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), nest, CreateNestIntrCmd, nest interrupt task test); +#endif diff --git a/example/system/nested_interrupt/src/nested_interrupt.c b/example/system/nested_interrupt/src/nested_interrupt.c index 84ae9b08a72fa974667be3081333e430ade92549..d90e59b6a60eb022b2cd778332a56b95bd67ae06 100644 --- a/example/system/nested_interrupt/src/nested_interrupt.c +++ b/example/system/nested_interrupt/src/nested_interrupt.c @@ -20,9 +20,11 @@ * Ver   Who        Date         Changes * ----- ------     --------    -------------------------------------- * 1.0 wangxiaodong 2023/2/23 first release + * 1.1 zhangyan 2024/4/29 add no letter shell mode, adapt to auto-test system */ #include +#include #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" @@ -32,8 +34,19 @@ #include "fcpu_info.h" #include "fexception.h" +enum +{ + NESTED_INTR_TEST_SUCCESS = 0, + NESTED_INTR_TEST_UNKNOWN = 1, + NESTED_INTR_TEST_FAILURE = 2, +}; +static QueueHandle_t xQueue = NULL; + +#define NESTED_INTR_TEST_TASK_PRIORITY 3 -static xTaskHandle xtask_handle; +#define TIMER_OUT (pdMS_TO_TICKS(1000UL)) +#define DELAT_PER_TEST (pdMS_TO_TICKS(100UL)) +#define TEST_TIMES 5 #define TASK_STACK_SIZE 1024 @@ -56,44 +69,42 @@ counter intuitive. */ static void vTriggerNestedInterrupt(void); static u32 cpu_id = 0; - -static volatile u8 low_priority_intr_flag = 0; /* Flag to update low priority interrupt counter */ static volatile u8 high_priority_intr_flag = 0; /* Flag to update high priority interrupt counter */ -float val_low = 0.3; -float val_high = 0.1; +/*The initial value of the calculated values for high priority and low priority tasks*/ +float val_low = 1.0; +float val_high = 1.0; -static void vNestedPeriodTask(void *pvParameters) +/*The final correct calculation result value*/ +#define VAL_HIGH_CALC_RES (float)1.104081 +#define VAL_LOW_CALC_RES (float)1.051010 + + +static void vNestedPeriod(void) { u8 count = 0; - for (count = 0; count < 10; count++) + for (count = 0; count < TEST_TIMES; count++) { - printf("Nested Interrupt Test %d.\r\n", count); vTriggerNestedInterrupt(); - vTaskDelay(1000 / portTICK_RATE_MS); + vTaskDelay(DELAT_PER_TEST); } - vTaskDelete(NULL); } static void FLowPriorityHandlerFunc(void) { val_low = val_low * 1.01; - /* Update the flag to indicate the interrupt */ - low_priority_intr_flag++; - /* Activate high-priority intr */ InterruptCoreInterSend(INTERRUPT_HIGH_ID, (1 << cpu_id)); /* Wait till interrupts from counter configured with high priority interrupt */ while(high_priority_intr_flag == 0); - printf("low_priority_intr_flag is %d, val_low=%f\r\n", low_priority_intr_flag, val_low); + printf("val_low = %f \r\n", val_low); } static void FLowPriorityHandler(s32 vector, void *param) { - static fsize_t value[3] = {0}; /* Enable the nested interrupts to allow preemption */ @@ -104,86 +115,109 @@ static void FLowPriorityHandler(s32 vector, void *param) /* Disable the nested interrupt before exiting IRQ mode */ FInterruptNestedDisable(value); - } static void FHighPriorityHandlerFunc(void) { high_priority_intr_flag++; + val_high = val_high * 1.02; - val_high = val_high * 1.01; - - printf("high_priority_intr_flag is %d, val_high=%f\r\n", high_priority_intr_flag, val_high); + printf("val_high = %f \r\n", val_high); } - static void FHighPriorityHandler(s32 vector, void *param) { - static fsize_t value[3] = {0}; /* Enable the nested interrupts to allow preemption */ FInterruptNestedEnable(value); - /* A function operation must be used between interrupt nesting enable and disable */ FHighPriorityHandlerFunc(); - /* Disable the nested interrupt before exiting IRQ mode */ FInterruptNestedDisable(value); - } - static void prvSetupSoftwareNestedInterrupt() { - GetCpuId(&cpu_id); - /* The interrupt service routine uses an (interrupt safe) FreeRTOS API function so the interrupt priority must be at or below the priority defined by configSYSCALL_INTERRUPT_PRIORITY. */ InterruptSetPriority(INTERRUPT_LOW_ID, INTERRUPT_LOW_PRIORITY); - InterruptInstall(INTERRUPT_LOW_ID, FLowPriorityHandler, NULL, NULL); - - /* Enable the interrupt. */ - InterruptUmask(INTERRUPT_LOW_ID); + InterruptUmask(INTERRUPT_LOW_ID);/* Enable the interrupt. */ InterruptSetPriority(INTERRUPT_HIGH_ID, INTERRUPT_HIGH_PRIORITY); - InterruptInstall(INTERRUPT_HIGH_ID, FHighPriorityHandler, NULL, NULL); - - /* Enable the interrupt. */ - InterruptUmask(INTERRUPT_HIGH_ID); - + InterruptUmask(INTERRUPT_HIGH_ID); /* Enable the interrupt. */ } /* Macro to force an interrupt. */ static void vTriggerNestedInterrupt(void) { - low_priority_intr_flag = 0; - high_priority_intr_flag = 0; - + /* Activate low-priority intr */ InterruptCoreInterSend(INTERRUPT_LOW_ID, (1 << cpu_id)); - } -void CreateNestedTasks(void) +void NestedIntrTask(void) { - printf("Create Nest Task \r\n"); + int task_res = NESTED_INTR_TEST_SUCCESS; prvSetupSoftwareNestedInterrupt(); - xTaskCreate(vNestedPeriodTask, "NestedPeriodic", TASK_STACK_SIZE, NULL, 6, &xtask_handle); + vNestedPeriod(); + /*取1E-6精度下比较计算结果,此精度可修改*/ + if (fabs(val_low - VAL_LOW_CALC_RES) <= 1E-6 || fabs(val_high - VAL_HIGH_CALC_RES) <= 1E-6) + { + task_res = NESTED_INTR_TEST_FAILURE; + } + + xQueueSend(xQueue, &task_res, 0); + vTaskDelete(NULL); } -void DeleteNestedTasks(void) +BaseType_t FFreeRTOSNestedIntrTaskCreate(void) { - if (xtask_handle) + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + int task_res = NESTED_INTR_TEST_UNKNOWN; + + xQueue = xQueueCreate(1, sizeof(int)); + if (xQueue == NULL) { - vTaskDelete(xtask_handle); - printf("Nest Periodic deletion \r\n"); + printf("xQueue create failed.\r\n"); + goto exit; } + xReturn = xTaskCreate((TaskFunction_t)NestedIntrTask, /* 任务入口函数 */ + (const char *)"NestedIntrTask", /* 任务名字 */ + (uint16_t)TASK_STACK_SIZE, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)NESTED_INTR_TEST_TASK_PRIORITY, /* 任务的优先级 */ + NULL); + if (xReturn == pdFAIL) + { + printf("xTaskCreate NestedIntrTask failed."); + goto exit; + } + + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + printf("xQueue receive timeout.\r\n"); + goto exit; + } + +exit: + vQueueDelete(xQueue); + if (task_res != NESTED_INTR_TEST_SUCCESS) + { + printf("%s@%d: Nested intr test example [failure], task_res = %d\r\n", __func__, __LINE__, task_res); + return pdFAIL; + } + else + { + printf("%s@%d: Nested intr test indirect example [success].\r\n", __func__, __LINE__); + return pdTRUE; + } } \ No newline at end of file diff --git a/example/system/posix/README.md b/example/system/posix/README.md index 8793bffd8eb5d87af51ac11fa8440fc048ac0fd2..cf9a7772619ab2250c3e2abbb2a03d666192c427 100644 --- a/example/system/posix/README.md +++ b/example/system/posix/README.md @@ -1,18 +1,25 @@ # posix base on freertos -## 1. 例程介绍 - -本例程示范了freertos环境下posix的使用方法。 POSIX (Portable Operating System Interface) 是定义了操作系统 API 的标准,主要用于通用操作系统,例如 Linux、UNIX 等。 通过在freertos上增加posix适配层,使得在 freertos 上开发的应用程序能够以 posix 的风格编写和移植。 -- [FreeRTOS-Plus-POSIX](https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_POSIX/index.html) +请参考[FreeRTOS官方网站](https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_POSIX/index.html) + +## 1. 例程介绍 + +posix测试用例 (posix_example.c) +- 创建POSIXDemoTask测试任务,在POSIXDemoTask中首先创建4个消息队列,4个prvWorkerThread线程,1个prvDispatcherThread线程 +- 每个prvWorkerThread用来等待接收1个消息队列中传递来的消息 +- 在prvDispatcherThread线程中,首先循环向4个消息队列发送100次`eWORKER_CTRL_MSG_CONTINUE`消息,4个prvWorkerThread线程依次接收到发来的消息 +- prvDispatcherThread线程发送`eWORKER_CTRL_MSG_EXIT`,4个prvWorkerThread线程依次接收到该消息后终止返回 +- prvDispatcherThread线程终止返回 +- POSIXDemoTask任务检测到所有创建的线程均已终止,测试结束 ## 2. 如何使用例程 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 @@ -105,9 +112,6 @@ bootelf -p 0x90100000 - 系统进入后,输入 ``posix``查看指令说明 -- 输入 ``posix thread``,启动线程的创建和等待测试 -![posix_thread](./figs/posix_thread.png) - - 输入 ``posix demo``,启动线程间的数据收发测试 ![posix_demo](./figs/posix_demo.png) diff --git a/example/system/posix/figs/posix_demo.png b/example/system/posix/figs/posix_demo.png index 7f60061cb9bd535a541b82b7f9d2e598c1bf3326..c451e16fc429a4b8275d698987584d1ce0d25630 100644 Binary files a/example/system/posix/figs/posix_demo.png and b/example/system/posix/figs/posix_demo.png differ diff --git a/example/system/posix/figs/posix_thread.png b/example/system/posix/figs/posix_thread.png deleted file mode 100644 index d8588c1e0d3a6e4fb604658966e63f6c6cd44ab5..0000000000000000000000000000000000000000 Binary files a/example/system/posix/figs/posix_thread.png and /dev/null differ diff --git a/example/system/posix/inc/posix_example.h b/example/system/posix/inc/posix_example.h index 429373a7e0391702282cc33ec1eb4241953d91e2..d95aa304304956852e4977e3b0b1dcba31836d23 100644 --- a/example/system/posix/inc/posix_example.h +++ b/example/system/posix/inc/posix_example.h @@ -26,14 +26,15 @@ #ifndef POSIX_EXAMPLE_H #define POSIX_EXAMPLE_H +#include "FreeRTOS.h" + #ifdef __cplusplus extern "C" { #endif /* POSIX Demo task */ -void CreatePOSIXDemoTasks(void); -void CreateThreadDemoTasks(void); +BaseType_t CreatePOSIXDemoTasks(void); #ifdef __cplusplus } diff --git a/example/system/posix/main.c b/example/system/posix/main.c index 6c611a23f8573e5629eab517d606b4604fd49c5a..3e893bb61fe0cf51244a04e1af91714de8f5c447 100644 --- a/example/system/posix/main.c +++ b/example/system/posix/main.c @@ -24,17 +24,39 @@ #include #include #include "FreeRTOS.h" -#include "task.h" #include "ftypes.h" + +#ifdef CONFIG_USE_LETTER_SHELL #include "shell.h" #include "shell_port.h" +#else +#include "task.h" +#include "posix_example.h" +#define FREERTOS_POSIX_EXAMPLE_TASK_PRIORITY 2 +void FFreeRTOSPosixExampleTaskEntry() +{ + CreatePOSIXDemoTasks(); + + printf("[test_end]\r\n"); + + vTaskDelete(NULL); +} +#endif int main() { - printf("Hello main func,FT Date: %s, Time: %s\n", __DATE__, __TIME__); BaseType_t xReturn = pdPASS; +#ifdef CONFIG_USE_LETTER_SHELL xReturn = LSUserShellTask(); +#else + xReturn = xTaskCreate((TaskFunction_t)FFreeRTOSPosixExampleTaskEntry, /* 任务入口函数 */ + (const char *)"FFreeRTOSPosixExampleTaskEntry", /* 任务名字 */ + (uint16_t)4096, /* 任务栈大小 */ + NULL, /* 任务入口函数参数 */ + (UBaseType_t)FREERTOS_POSIX_EXAMPLE_TASK_PRIORITY, /* 任务的优先级 */ + NULL); +#endif if (xReturn != pdPASS) { goto FAIL_EXIT; diff --git a/example/system/posix/src/posix_example.c b/example/system/posix/src/posix_example.c index 9fcd478f00678a89ccee978edfd927ffc29a0c46..2a6f516d33876b9741453728375c8344f4d6975d 100644 --- a/example/system/posix/src/posix_example.c +++ b/example/system/posix/src/posix_example.c @@ -31,8 +31,9 @@ #include "FreeRTOSConfig.h" #include "FreeRTOS.h" #include "task.h" -#include "fatomic.h" -#include "fkernel.h" +#include "fdebug.h" +#include "fassert.h" +#include "posix_example.h" /* FreeRTOS+POSIX. */ #include "FreeRTOS_POSIX.h" @@ -42,12 +43,24 @@ #include "FreeRTOS_POSIX/fcntl.h" #include "FreeRTOS_POSIX/errno.h" -static xTaskHandle xtask_handle; +#define FPOSIX_DEBUG_TAG "POSIX_TEST" +#define FPOSIX_ERROR(format, ...) FT_DEBUG_PRINT_E(FPOSIX_DEBUG_TAG, format, ##__VA_ARGS__) +#define FPOSIX_WARN(format, ...) FT_DEBUG_PRINT_W(FPOSIX_DEBUG_TAG, format, ##__VA_ARGS__) +#define FPOSIX_INFO(format, ...) FT_DEBUG_PRINT_I(FPOSIX_DEBUG_TAG, format, ##__VA_ARGS__) +#define FPOSIX_DEBUG(format, ...) FT_DEBUG_PRINT_D(FPOSIX_DEBUG_TAG, format, ##__VA_ARGS__) -#define TASK_STACK_SIZE 1024 +enum +{ + POSIX_TEST_SUCCESS = 0, + POSIX_TEST_UNKNOWN = 1, + POSIX_TEST_FAILURE = 2, +}; +#define TIMER_OUT (pdMS_TO_TICKS(5000UL)) +static QueueHandle_t xQueue = NULL; +static xTaskHandle xtask_handle; -/* Constants. */ -#define LINE_BREAK "\r\n" +#define TASK_STACK_SIZE 1024 +#define LINE_BREAK "\r\n" /* Constants. */ /** * @brief Control messages. @@ -63,7 +76,6 @@ typedef enum ControlMessage eWORKER_CTRL_MSG_EXIT = 0x02, /**< Dispatcher to worker, all jobs are finished and the worker receiving such can exit. */ /* define additional messages here */ - eMSG_UPPER_INVALID = 0xFF /**< Guard, additional tasks shall be defined above. */ } eControlMessage; /**@} */ @@ -72,20 +84,24 @@ typedef enum ControlMessage * @defgroup Configuration constants for the dispatcher-worker demo. */ /**@{ */ -#define MQUEUE_NUMBER_OF_WORKERS ( 4 ) /**< The number of worker threads, each thread has one queue which is used as income box. */ +#define MQUEUE_NUMBER_OF_WORKERS (4) /**< The number of worker threads, each thread has one queue which is used as income box. */ -#if ( MQUEUE_NUMBER_OF_WORKERS > 10 ) - #error "Please keep MQUEUE_NUMBER_OF_WORKERS < 10." +#if (MQUEUE_NUMBER_OF_WORKERS > 10) +#error "Please keep MQUEUE_NUMBER_OF_WORKERS < 10." #endif -#define MQUEUE_WORKER_QNAME_BASE "/qNode0" /**< Queue name base. */ -#define MQUEUE_WORKER_QNAME_BASE_LEN ( 6 ) /** Queue name base length. */ +#define MQUEUE_WORKER_QNAME_BASE "/qNode0" /**< Queue name base. */ +#define MQUEUE_WORKER_QNAME_BASE_LEN (6) /** Queue name base length. */ + +#define MQUEUE_TIMEOUT_SECONDS (1) /**< Relative timeout for mqueue functions. */ +#define MQUEUE_MAX_NUMBER_OF_MESSAGES_WORKER (1) /**< Maximum number of messages in a queue. */ -#define MQUEUE_TIMEOUT_SECONDS ( 1 ) /**< Relative timeout for mqueue functions. */ -#define MQUEUE_MAX_NUMBER_OF_MESSAGES_WORKER ( 1 ) /**< Maximum number of messages in a queue. */ +#define MQUEUE_MSG_WORKER_CTRL_MSG_SIZE sizeof(uint8_t) /**< Control message size. */ +#define MESSAGE_TRAN_SUCCESS 0 +#define MESSAGE_TRAN_FAILED -1 +#define POSIX_DEMO__TASK_PRIORITY 3 -#define MQUEUE_MSG_WORKER_CTRL_MSG_SIZE sizeof( uint8_t ) /**< Control message size. */ -#define DEMO_ERROR ( -1 ) /**< Any non-zero value would work. */ +static int message_correct_flag = MESSAGE_TRAN_SUCCESS; /**@} */ /** @@ -105,59 +121,68 @@ typedef struct WorkerThreadResources /**@{ */ typedef struct DispatcherThreadResources { - pthread_t pxID; /**< thread ID. */ - mqd_t * pOutboxID; /**< a list of mqueue outbox ID. */ + pthread_t pxID; /**< thread ID. */ + mqd_t *pOutboxID; /**< a list of mqueue outbox ID. */ } DispatcherThreadResources_t; /**@} */ /*-----------------------------------------------------------*/ -static void * prvWorkerThread( void * pvArgs ) +static void *prvWorkerThread(void *pvArgs) { - WorkerThreadResources_t pArgList = *( WorkerThreadResources_t * ) pvArgs; + if (message_correct_flag != MESSAGE_TRAN_SUCCESS) + { + FPOSIX_ERROR("prvWorkerThread check message_correct_flag error."); + + return NULL; + } + WorkerThreadResources_t pArgList = *(WorkerThreadResources_t *)pvArgs; - printf( "Worker thread #[%d] - start %s", ( int ) pArgList.pxID, LINE_BREAK ); + FPOSIX_DEBUG("Worker thread #[%d] - start %s", (int)pArgList.pxID, LINE_BREAK); - struct timespec xReceiveTimeout = { 0 }; + struct timespec xReceiveTimeout = {0}; ssize_t xMessageSize = 0; - char pcReceiveBuffer[ MQUEUE_MSG_WORKER_CTRL_MSG_SIZE ] = { 0 }; + char pcReceiveBuffer[MQUEUE_MSG_WORKER_CTRL_MSG_SIZE] = {0}; /* This is a worker thread that reacts based on what is sent to its inbox (mqueue). */ - while( true ) + while (true) { - clock_gettime( CLOCK_REALTIME, &xReceiveTimeout ); + clock_gettime(CLOCK_REALTIME, &xReceiveTimeout); xReceiveTimeout.tv_sec += MQUEUE_TIMEOUT_SECONDS; - xMessageSize = mq_receive( pArgList.xInboxID, - pcReceiveBuffer, - MQUEUE_MSG_WORKER_CTRL_MSG_SIZE, - 0 ); + xMessageSize = mq_receive(pArgList.xInboxID, + pcReceiveBuffer, + MQUEUE_MSG_WORKER_CTRL_MSG_SIZE, + 0); /* Parse messages */ - if( xMessageSize == MQUEUE_MSG_WORKER_CTRL_MSG_SIZE ) + if (xMessageSize == MQUEUE_MSG_WORKER_CTRL_MSG_SIZE) { - switch( ( int ) pcReceiveBuffer[ 0 ] ) + switch ((int)pcReceiveBuffer[0]) { - case eWORKER_CTRL_MSG_CONTINUE: - /* Task branch, currently only prints message to screen. */ - /* Could perform tasks here. Could also notify dispatcher upon completion, if desired. */ - printf( "Worker thread #[%d] -- Received eWORKER_CTRL_MSG_CONTINUE %s", ( int ) pArgList.pxID, LINE_BREAK ); - break; + case eWORKER_CTRL_MSG_CONTINUE: + /* Task branch, currently only prints message to screen. */ + /* Could perform tasks here. Could also notify dispatcher upon completion, if desired. */ + FPOSIX_DEBUG("Worker thread #[%d] -- Received eWORKER_CTRL_MSG_CONTINUE %s", (int)pArgList.pxID, LINE_BREAK); + break; - case eWORKER_CTRL_MSG_EXIT: - printf( "Worker thread #[%d] -- Finished. Exit now. %s", ( int ) pArgList.pxID, LINE_BREAK ); + case eWORKER_CTRL_MSG_EXIT: + FPOSIX_DEBUG("Worker thread #[%d] -- Finished. Exit now. %s", (int)pArgList.pxID, LINE_BREAK); - return NULL; + return NULL; - default: - /* Received a message that we don't care or not defined. */ - break; + default: + /* Received a message that we don't care or not defined. */ + break; } } else { - /* Invalid message. Error handling can be done here, if desired. */ + FPOSIX_ERROR("prvWorkerThread mq_receive error."); + message_correct_flag = MESSAGE_TRAN_FAILED; + + return NULL; } } @@ -167,59 +192,65 @@ static void * prvWorkerThread( void * pvArgs ) /*-----------------------------------------------------------*/ -static void * prvDispatcherThread( void * pvArgs ) +static void *prvDispatcherThread(void *pvArgs) { - DispatcherThreadResources_t pArgList = *( DispatcherThreadResources_t * ) pvArgs; + DispatcherThreadResources_t pArgList = *(DispatcherThreadResources_t *)pvArgs; - printf( "Dispatcher thread - start %s", LINE_BREAK ); + FPOSIX_DEBUG("Dispatcher thread - start %s", LINE_BREAK); - struct timespec xSendTimeout = { 0 }; + struct timespec xSendTimeout = {0}; - ssize_t xMessageSize = 0; - char pcSendBuffer[ MQUEUE_MSG_WORKER_CTRL_MSG_SIZE ] = { 0 }; + int iStatus = 0; + char pcSendBuffer[MQUEUE_MSG_WORKER_CTRL_MSG_SIZE] = {0}; /* Just for fun, let threads do a total of 100 independent tasks. */ int i = 0; const int totalNumOfJobsPerThread = 100; /* Distribute 1000 independent tasks to workers, in round-robin fashion. */ - pcSendBuffer[ 0 ] = ( char ) eWORKER_CTRL_MSG_CONTINUE; + pcSendBuffer[0] = (char)eWORKER_CTRL_MSG_CONTINUE; - for( i = 0; i < totalNumOfJobsPerThread; i++ ) + for (i = 0; i < totalNumOfJobsPerThread; i++) { - clock_gettime( CLOCK_REALTIME, &xSendTimeout ); - xSendTimeout.tv_sec += MQUEUE_TIMEOUT_SECONDS; - - printf( "Dispatcher iteration #[%d] -- Sending msg to worker thread #[%d]. %s", i, ( int ) pArgList.pOutboxID[ i % MQUEUE_NUMBER_OF_WORKERS ], LINE_BREAK ); - - xMessageSize = mq_timedsend( pArgList.pOutboxID[ i % MQUEUE_NUMBER_OF_WORKERS ], - pcSendBuffer, - MQUEUE_MSG_WORKER_CTRL_MSG_SIZE, - 0, - &xSendTimeout ); + if (message_correct_flag != MESSAGE_TRAN_SUCCESS) + { + FPOSIX_ERROR("prvDispatcherThread check message_correct_flag error."); - if( xMessageSize != 0 ) + return NULL; + } + + clock_gettime(CLOCK_REALTIME, &xSendTimeout); + xSendTimeout.tv_sec += MQUEUE_TIMEOUT_SECONDS; + FPOSIX_DEBUG("Dispatcher iteration #[%d] -- Sending msg to worker thread #[%d]. %s", i, (int)pArgList.pOutboxID[i % MQUEUE_NUMBER_OF_WORKERS], LINE_BREAK); + + iStatus = mq_timedsend(pArgList.pOutboxID[i % MQUEUE_NUMBER_OF_WORKERS], + pcSendBuffer, + MQUEUE_MSG_WORKER_CTRL_MSG_SIZE, + 0, + &xSendTimeout); + if (iStatus != 0) { /* This error is acceptable in our setup. * Since inbox for each thread fits only one message. * In reality, balance inbox size, message arrival rate, and message drop rate. */ - printf( "An acceptable failure -- dispatcher failed to send eWORKER_CTRL_MSG_CONTINUE to outbox ID: %x. errno %d %s", - ( int ) pArgList.pOutboxID[ i % MQUEUE_NUMBER_OF_WORKERS ], errno, LINE_BREAK ); + FPOSIX_ERROR("An acceptable failure -- dispatcher failed to send eWORKER_CTRL_MSG_CONTINUE to outbox ID: %x. errno %d %s", + (int)pArgList.pOutboxID[i % MQUEUE_NUMBER_OF_WORKERS], errno, LINE_BREAK); + + return NULL; } } /* Control thread is now done with distributing jobs. Tell workers they are done. */ - pcSendBuffer[ 0 ] = ( char ) eWORKER_CTRL_MSG_EXIT; + pcSendBuffer[0] = (char)eWORKER_CTRL_MSG_EXIT; - for( i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++ ) + for (i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++) { - printf( "Dispatcher [%d] -- Sending eWORKER_CTRL_MSG_EXIT to worker thread #[%d]. %s", i, ( int ) pArgList.pOutboxID[ i % MQUEUE_NUMBER_OF_WORKERS ], LINE_BREAK ); - + FPOSIX_DEBUG("Dispatcher [%d] -- Sending eWORKER_CTRL_MSG_EXIT to worker thread #[%d]. %s", i, (int)pArgList.pOutboxID[i % MQUEUE_NUMBER_OF_WORKERS], LINE_BREAK); /* This is a blocking call, to guarantee worker thread exits. */ - xMessageSize = mq_send( pArgList.pOutboxID[ i % MQUEUE_NUMBER_OF_WORKERS ], - pcSendBuffer, - MQUEUE_MSG_WORKER_CTRL_MSG_SIZE, - 0 ); + iStatus = mq_send(pArgList.pOutboxID[i % MQUEUE_NUMBER_OF_WORKERS], + pcSendBuffer, + MQUEUE_MSG_WORKER_CTRL_MSG_SIZE, + 0); } return NULL; @@ -232,121 +263,156 @@ static void * prvDispatcherThread( void * pvArgs ) * * See the top of this file for detailed description. */ -void vStartPOSIXDemo( void *pvParameters ) +void POSIXDemoTask(void) { int i = 0; int iStatus = 0; - - /* Remove warnings about unused parameters. */ - ( void ) pvParameters; + int task_res = POSIX_TEST_SUCCESS; /* Handles of the threads and related resources. */ - DispatcherThreadResources_t pxDispatcher = { 0 }; - WorkerThreadResources_t pxWorkers[ MQUEUE_NUMBER_OF_WORKERS ] = { { 0 } }; - mqd_t workerMqueues[ MQUEUE_NUMBER_OF_WORKERS ] = { 0 }; + DispatcherThreadResources_t pxDispatcher = {0}; + WorkerThreadResources_t pxWorkers[MQUEUE_NUMBER_OF_WORKERS] = {{0}}; + mqd_t workerMqueues[MQUEUE_NUMBER_OF_WORKERS] = {0}; struct mq_attr xQueueAttributesWorker = - { - .mq_flags = 0, - .mq_maxmsg = MQUEUE_MAX_NUMBER_OF_MESSAGES_WORKER, - .mq_msgsize = MQUEUE_MSG_WORKER_CTRL_MSG_SIZE, - .mq_curmsgs = 0 - }; + { + .mq_flags = 0, + .mq_maxmsg = MQUEUE_MAX_NUMBER_OF_MESSAGES_WORKER, + .mq_msgsize = MQUEUE_MSG_WORKER_CTRL_MSG_SIZE, + .mq_curmsgs = 0 + }; pxDispatcher.pOutboxID = workerMqueues; /* Create message queues for each worker thread. */ - for( i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++ ) + for (i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++) { /* Prepare a unique queue name for each worker. */ char qName[] = MQUEUE_WORKER_QNAME_BASE; - qName[ MQUEUE_WORKER_QNAME_BASE_LEN - 1 ] = qName[ MQUEUE_WORKER_QNAME_BASE_LEN - 1 ] + i; + qName[MQUEUE_WORKER_QNAME_BASE_LEN - 1] = qName[MQUEUE_WORKER_QNAME_BASE_LEN - 1] + i; /* Open a queue with -- * O_CREAT -- create a message queue. * O_RDWR -- both receiving and sending messages. */ - pxWorkers[ i ].xInboxID = mq_open( qName, - O_CREAT | O_RDWR, - ( mode_t ) 0, - &xQueueAttributesWorker ); + pxWorkers[i].xInboxID = mq_open(qName, + O_CREAT | O_RDWR, + (mode_t)0, + &xQueueAttributesWorker); - if( pxWorkers[ i ].xInboxID == ( mqd_t ) -1 ) + if (pxWorkers[i].xInboxID == (mqd_t)-1) { - printf( "Invalid inbox (mqueue) for worker. %s", LINE_BREAK ); - iStatus = DEMO_ERROR; - break; + FPOSIX_ERROR("Invalid inbox (mqueue) for worker. %s", LINE_BREAK); + iStatus = -1; + task_res = POSIX_TEST_FAILURE; + goto task_exit; } /* Outboxes of dispatcher thread is the inboxes of all worker threads. */ - pxDispatcher.pOutboxID[ i ] = pxWorkers[ i ].xInboxID; + pxDispatcher.pOutboxID[i] = pxWorkers[i].xInboxID; } /* Create and start Worker threads. */ - if( iStatus == 0 ) + if (iStatus == 0) { - for( i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++ ) + for (i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++) { - ( void ) pthread_create( &( pxWorkers[ i ].pxID ), NULL, prvWorkerThread, &pxWorkers[ i ] ); + iStatus = pthread_create(&(pxWorkers[i].pxID), NULL, prvWorkerThread, &pxWorkers[i]); + if (iStatus != 0) + { + task_res = POSIX_TEST_FAILURE; + goto task_exit; + } } /* Create and start dispatcher thread. */ - ( void ) pthread_create( &( pxDispatcher.pxID ), NULL, prvDispatcherThread, &pxDispatcher ); + iStatus = pthread_create(&(pxDispatcher.pxID), NULL, prvDispatcherThread, &pxDispatcher); + if (iStatus != 0) + { + task_res = POSIX_TEST_FAILURE; + goto task_exit; + } /* Actors will do predefined tasks in threads. Current implementation is that * dispatcher actor notifies worker actors to terminate upon finishing distributing tasks. */ /* Wait for worker threads to join. */ - for( i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++ ) + for (i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++) { - ( void ) pthread_join( pxWorkers[ i ].pxID, NULL ); + (void)pthread_join(pxWorkers[i].pxID, NULL); } /* Wait for dispatcher thread to join. */ - ( void ) pthread_join( pxDispatcher.pxID, NULL ); + (void)pthread_join(pxDispatcher.pxID, NULL); } /* Close and unlink worker message queues. */ - for( i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++ ) + for (i = 0; i < MQUEUE_NUMBER_OF_WORKERS; i++) { char qName[] = MQUEUE_WORKER_QNAME_BASE; - qName[ MQUEUE_WORKER_QNAME_BASE_LEN - 1 ] = qName[ MQUEUE_WORKER_QNAME_BASE_LEN - 1 ] + i; + qName[MQUEUE_WORKER_QNAME_BASE_LEN - 1] = qName[MQUEUE_WORKER_QNAME_BASE_LEN - 1] + i; - if( pxWorkers[ i ].xInboxID != NULL ) + if (pxWorkers[i].xInboxID != NULL) { - ( void ) mq_close( pxWorkers[ i ].xInboxID ); - ( void ) mq_unlink( qName ); + (void)mq_close(pxWorkers[i].xInboxID); + (void)mq_unlink(qName); } } - /* Have something on console. */ - if( iStatus == 0 ) + if (iStatus == 0 && message_correct_flag == MESSAGE_TRAN_SUCCESS) { - printf( "All threads finished. %s", LINE_BREAK ); + printf("All threads finished. %s", LINE_BREAK); } else { - printf( "Queues did not get initialized properly. Did not run demo. %s", LINE_BREAK ); + FPOSIX_ERROR("Queues did not get initialized properly. Did not run demo. %s", LINE_BREAK); + task_res = POSIX_TEST_FAILURE; } - /* This task was created with the native xTaskCreate() API function, so - must not run off the end of its implementing thread. */ - vTaskDelete( NULL ); - +task_exit: + xQueueSend(xQueue, &task_res, 0); + /* This task was created with the native xTaskCreate() API function, so + must not run off the end of its implementing thread. */ + vTaskDelete(NULL); } -void CreatePOSIXDemoTasks(void) +BaseType_t CreatePOSIXDemoTasks(void) { - printf("Create POSIXDemo Task \r\n"); - xTaskCreate(vStartPOSIXDemo, "POSIXDemo", TASK_STACK_SIZE, NULL, 6, &xtask_handle); + BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */ + BaseType_t xTimerStarted = pdPASS; + int task_res = POSIX_TEST_UNKNOWN; -} + xQueue = xQueueCreate(1, sizeof(int)); + if (xQueue == NULL) + { + FPOSIX_ERROR("xQueue create failed.\r\n"); + goto exit; + } -void DeletePOSIXDemoTasks(void) -{ - if (xtask_handle) + xReturn = xTaskCreate((TaskFunction_t)POSIXDemoTask, /* 任务入口函数 */ + (const char *)"POSIXDemoTask", /* 任务名字 */ + (uint16_t)TASK_STACK_SIZE, /* 任务栈大小 */ + (void *)NULL, /* 任务入口函数参数 */ + (UBaseType_t)POSIX_DEMO__TASK_PRIORITY, /* 任务的优先级 */ + &xtask_handle); /* 任务控制 */ + FASSERT_MSG(xReturn == pdPASS, "POSIXDemoTask creation is failed."); + + xReturn = xQueueReceive(xQueue, &task_res, TIMER_OUT); + if (xReturn == pdFAIL) + { + FPOSIX_ERROR("xQueue receive timeout.\r\n"); + goto exit; + } + +exit: + if (task_res != POSIX_TEST_SUCCESS || message_correct_flag != MESSAGE_TRAN_SUCCESS) { - vTaskDelete(xtask_handle); - printf("POSIXDemo deletion \r\n"); + printf("%s@%d: Posix test example [failure], task_res = %d.\r\n", __func__, __LINE__, task_res); + return pdFAIL; } -} \ No newline at end of file + else + { + printf("%s@%d: Posix test example [success].\r\n", __func__, __LINE__); + return pdTRUE; + } +} diff --git a/example/system/posix/src/posix_example_cmd.c b/example/system/posix/src/posix_example_cmd.c index 38e211e1cb06115e9174431e78e15c573e05b71d..643f75d81010108d0ca10cae88ba12e0568d66d6 100644 --- a/example/system/posix/src/posix_example_cmd.c +++ b/example/system/posix/src/posix_example_cmd.c @@ -24,36 +24,28 @@ #include #include -#include "shell.h" #include "posix_example.h" +#include "sdkconfig.h" +#ifdef CONFIG_USE_LETTER_SHELL +#include "shell.h" static void CreatePosixCmdUsage(void) { printf("Usage:\r\n"); - printf(" posix thread \r\n"); - printf(" -- Create posix thread test now.\r\n"); printf(" posix demo \r\n"); printf(" -- Create posix test now.\r\n"); } int CreatePosixCmd(int argc, char *argv[]) { - static int create_flg = 0; /* 1 is tasks has been created*/ - if (argc < 2) { CreatePosixCmdUsage(); return -1; } - if (!strcmp(argv[1], "demo")) - { - CreatePOSIXDemoTasks(); - } - - if (!strcmp(argv[1], "thread")) { - CreateThreadDemoTasks(); + CreatePOSIXDemoTasks(); } else @@ -63,7 +55,5 @@ int CreatePosixCmd(int argc, char *argv[]) } return 0; } - SHELL_EXPORT_CMD(SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), posix, CreatePosixCmd, posix task test); - - +#endif diff --git a/example/template/README.md b/example/template/README.md index 81b7f18ba1cab8b479561141d39c62e8d738a67a..d55349948c0012aa18fbb19b90f512c849e2f61d 100644 --- a/example/template/README.md +++ b/example/template/README.md @@ -8,7 +8,7 @@ 本例程需要用到 - Phytium开发板(FT2000-4/D2000/E2000D/E2000Q/PHYTIUMPI) -- [Phytium freeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) +- [Phytium FreeRTOS SDK](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk) - [Phytium standalone SDK](https://gitee.com/phytium_embedded/phytium-standalone-sdk) ### 2.1 硬件配置方法 diff --git a/example/template/makefile b/example/template/makefile index 2b634142f2f04dc3e9ba76d6c16af522e6d952b9..d8139e9cbf8512f973c85c0f528ad6a1a83f4ddb 100644 --- a/example/template/makefile +++ b/example/template/makefile @@ -19,8 +19,8 @@ include $(FREERTOS_SDK_DIR)/tools/makeall.mk USR_BOOT_DIR ?= /mnt/d/tftboot image: - $(MAKE) clean - $(MAKE) all -j + @$(MAKE) -s clean + @$(MAKE) -s all -j @cp ./$(IMAGE_OUT_NAME).elf $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).elf ifdef CONFIG_OUTPUT_BINARY @cp ./$(IMAGE_OUT_NAME).bin $(USR_BOOT_DIR)/$(BOOT_IMG_NAME).bin diff --git a/install.py b/install.py index 00377a1bdf7249dd9c73d1be8175e450cc7a6a7e..6b303200767fb04e281934a304e9d6b05d3ee542 100755 --- a/install.py +++ b/install.py @@ -36,7 +36,7 @@ freertos_sdk_path = install_path print("Standalone SDK at {}".format(freertos_sdk_path)) # Add standalone sdk -standalone_sdk_v="169fd0f71e9e14b2c164c953ee86a7dcabf6c041" +standalone_sdk_v="b37fd3196b7890e5c90255d2dfa5c8d7a55a4828" if (install_platform == windows_x64): standalone_path=freertos_sdk_path + '\\standalone' else: @@ -73,4 +73,4 @@ else: pass ## STEP 2: display success message and enable environment -print("Success!!! Phytium FreeRTOS SDK is Install at {}".format(freertos_sdk_path)) \ No newline at end of file +print("Success!!! Phytium FreeRTOS SDK is Install at {}".format(freertos_sdk_path)) diff --git a/third-party/fatfs-0.1.4/src.mk b/third-party/fatfs-0.1.4/src.mk index 061e8659601e389477ee78bd09d4dc022b701060..e4c2945b7027081d00ab72d007d948716fcb1a9f 100644 --- a/third-party/fatfs-0.1.4/src.mk +++ b/third-party/fatfs-0.1.4/src.mk @@ -15,7 +15,7 @@ endif # CSRCS_RELATIVE_FILES += $(wildcard port/fsata_pcie/*.c) # endif -FATFS_RT_C_DIR = $(SDK_DIR)/third-party/fatfs-0.1.4 +FATFS_RT_C_DIR = $(abspath $(SDK_DIR)/third-party/fatfs-0.1.4) ABSOLUTE_CFILES += $(wildcard $(FATFS_RT_C_DIR)/utils/*.c) ABSOLUTE_CFILES += $(wildcard $(FATFS_RT_C_DIR)/port/*.c) diff --git a/third-party/fsl_sdmmc/src.mk b/third-party/fsl_sdmmc/src.mk index 724ecc97aec63faf6326aac11dc1ca1d370ddd89..c54173447f8af9be49a33412c4b6165632701062 100644 --- a/third-party/fsl_sdmmc/src.mk +++ b/third-party/fsl_sdmmc/src.mk @@ -1,35 +1,34 @@ -FSL_SDMMC_OS_DIR := $(FREERTOS_SDK_DIR)/third-party/fsl_sdmmc -FSL_SDMMC_BM_DIR := $(SDK_DIR)/third-party/fsl_sdmmc - -ABSOLUTE_CFILES += $(wildcard $(FSL_SDMMC_BM_DIR)/common/*.c) \ - $(wildcard $(FSL_SDMMC_BM_DIR)/host/*.c) \ - $(wildcard $(FSL_SDMMC_BM_DIR)/partition/*.c) ifdef CONFIG_USE_FREERTOS -ABSOLUTE_CFILES += $(wildcard $(FSL_SDMMC_OS_DIR)/osa/*.c) +ABSOLUTE_CFILES += $(wildcard osa/*.c) endif +FSL_SDMMC_BM_DIR := $(abspath $(SDK_DIR)/third-party/fsl_sdmmc) + +ABSOLUTE_CFILES += $(abspath $(wildcard $(FSL_SDMMC_BM_DIR)/common/*.c)) \ + $(abspath $(wildcard $(FSL_SDMMC_BM_DIR)/host/*.c)) \ + $(abspath $(wildcard $(FSL_SDMMC_BM_DIR)/partition/*.c)) + ifdef CONFIG_FSL_SDMMC_USE_FSDIF -ABSOLUTE_CFILES += $(wildcard $(FSL_SDMMC_BM_DIR)/host/fsdif/*.c) +ABSOLUTE_CFILES += $(abspath $(wildcard $(FSL_SDMMC_BM_DIR)/host/fsdif/*.c)) endif ifdef CONFIG_FSL_SDMMC_USE_FSDMMC -ABSOLUTE_CFILES += $(wildcard $(FSL_SDMMC_BM_DIR)/host/fsdmmc/*.c) +ABSOLUTE_CFILES += $(abspath $(wildcard $(FSL_SDMMC_BM_DIR)/host/fsdmmc/*.c)) endif ifdef CONFIG_FSL_SDMMC_ENABLE_SD -ABSOLUTE_CFILES += $(wildcard $(FSL_SDMMC_BM_DIR)/sd/*.c) +ABSOLUTE_CFILES += $(abspath $(wildcard $(FSL_SDMMC_BM_DIR)/sd/*.c)) endif ifdef CONFIG_FSL_SDMMC_ENABLE_MMC -ABSOLUTE_CFILES += $(wildcard $(FSL_SDMMC_BM_DIR)/mmc/*.c) +ABSOLUTE_CFILES += $(abspath $(wildcard $(FSL_SDMMC_BM_DIR)/mmc/*.c)) endif ifdef CONFIG_FSL_SDMMC_ENABLE_SDIO -ABSOLUTE_CFILES += $(wildcard $(FSL_SDMMC_BM_DIR)/sdio/*.c) +ABSOLUTE_CFILES += $(abspath $(wildcard $(FSL_SDMMC_BM_DIR)/sdio/*.c)) endif ifdef CONFIG_FSL_SDMMC_ENABLE_SD_SPI -ABSOLUTE_CFILES += $(wildcard $(FSL_SDMMC_BM_DIR)/sdspi/*.c) +ABSOLUTE_CFILES += $(abspath $(wildcard $(FSL_SDMMC_BM_DIR)/sdspi/*.c)) endif - diff --git a/third-party/fsl_wifi/port/os/os.c b/third-party/fsl_wifi/port/os/os.c index 85dc6c9cd144d90d48b7bf4b91281712baa7c45c..d053d12f0b0989b0453be14413bf587398aebd0b 100644 --- a/third-party/fsl_wifi/port/os/os.c +++ b/third-party/fsl_wifi/port/os/os.c @@ -121,7 +121,7 @@ void os_thread_sleep(uint32_t ticks) void os_thread_self_complete(os_thread_t *thandle) { /* Suspend self until someone calls delete. This is required because in - * freeRTOS, main functions of a thread cannot return. + * FreeRTOS, main functions of a thread cannot return. */ if (thandle != NULL) { diff --git a/third-party/fsl_wifi/port/sdio/wifi_bt_config.c b/third-party/fsl_wifi/port/sdio/wifi_bt_config.c index 01ef7de9c45a66c9eefb44b0c4079b2fafb4f00c..b34753b5b0381aeec1ff021325b79d9e86fc8676 100644 --- a/third-party/fsl_wifi/port/sdio/wifi_bt_config.c +++ b/third-party/fsl_wifi/port/sdio/wifi_bt_config.c @@ -62,13 +62,11 @@ static void SdioMW8801PowerUp(void) { gpio_config = *FGpioLookupConfig(FGPIO4_ID); (void)FGpioCfgInitialize(&gpio, &gpio_config); - + PDn_index.ctrl = FGPIO4_ID; PDn_index.port = FGPIO_PORT_A; PDn_index.pin = FGPIO_PIN_11; - FIOPadSetGpioMux(PDn_index.ctrl, (u32)PDn_index.pin); - (void)FGpioPinInitialize(&gpio, &PDn, PDn_index); (void)FGpioSetDirection(&PDn, FGPIO_DIR_OUTPUT); @@ -86,12 +84,9 @@ static void SdioMW8801PowerUp(void) void BOARD_WIFI_BT_Config(void *host, sdio_int_t cardInt) { sdmmc_sdio_t *sdio_host = (sdmmc_sdio_t *)host; - - SdioMW8801PowerUp(); - FSdifTimingInit(); + SdioMW8801PowerUp(); SDMMC_OSAInit(); - memset(&s_inst_config, 0, sizeof(s_inst_config)); memset(sdio_host, 0, sizeof(*sdio_host)); @@ -110,7 +105,6 @@ void BOARD_WIFI_BT_Config(void *host, sdio_int_t cardInt) s_inst_config.sdioCardIntArg = NULL; FIOPadSetSdMux(s_inst_config.hostId); - if (kStatus_Success != SDIO_CfgInitialize(sdio_host, &s_inst_config)) { PRINTF("Config SDIO failed !!! \r\n"); diff --git a/third-party/libmetal/src.mk b/third-party/libmetal/src.mk index bb2f59719a1563470310c34f2534fbcd21891eb6..dbe387d333bd40df26a26ee982007669a6fb347c 100644 --- a/third-party/libmetal/src.mk +++ b/third-party/libmetal/src.mk @@ -15,9 +15,9 @@ ifdef CONFIG_USE_FREERTOS endif -LIBMETAL_DIR = $(SDK_DIR)/third-party/libmetal +LIBMETAL_DIR = $(abspath $(SDK_DIR)/third-party/libmetal) -ABSOLUTE_CFILES +=$(wildcard $(LIBMETAL_DIR)/metal/*.c) +ABSOLUTE_CFILES +=$(wildcard $(LIBMETAL_DIR)/metal/*.c) endif #CONFIG_USE_LIBMETAL \ No newline at end of file diff --git a/third-party/lvgl-8.3/src.mk b/third-party/lvgl-8.3/src.mk index 0c95301cab10d70688a0fcef9158869de6ade3a4..e985385751ffb71e2648f6364ed9ad7990083a8e 100644 --- a/third-party/lvgl-8.3/src.mk +++ b/third-party/lvgl-8.3/src.mk @@ -1,7 +1,7 @@ ifdef CONFIG_USE_LVGL -LVGL_C_DIR = $(SDK_DIR)/third-party/lvgl-8.3 +LVGL_C_DIR = $(abspath $(SDK_DIR)/third-party/lvgl-8.3) ABSOLUTE_CFILES +=$(wildcard $(LVGL_C_DIR)/src/core/*.c) \ $(wildcard $(LVGL_C_DIR)/src/draw/*.c) \ diff --git a/third-party/lwip-2.1.2/src.mk b/third-party/lwip-2.1.2/src.mk index 33adc3793efb1aa87ee9bb52fd4064ae1708c051..e17899ea8a48d8c0d753b0d7f0000456a5600590 100644 --- a/third-party/lwip-2.1.2/src.mk +++ b/third-party/lwip-2.1.2/src.mk @@ -14,7 +14,7 @@ ifdef CONFIG_USE_FREERTOS endif -LWIP_RT_C_DIR = $(SDK_DIR)/third-party/lwip-2.1.2 +LWIP_RT_C_DIR = $(abspath $(SDK_DIR)/third-party/lwip-2.1.2) # src code of lwip ABSOLUTE_CFILES += $(wildcard $(LWIP_RT_C_DIR)/api/*.c) \ diff --git a/third-party/openamp/src.mk b/third-party/openamp/src.mk index dbd606509993a59fcb848b3919e85f82b4882efd..7b28f2c37a7435c090741290313f15471b4a01d7 100644 --- a/third-party/openamp/src.mk +++ b/third-party/openamp/src.mk @@ -6,7 +6,7 @@ ifdef CONFIG_USE_FREERTOS endif -OPENAMP_C_DIR = $(SDK_DIR)/third-party/openamp +OPENAMP_C_DIR = $(abspath $(SDK_DIR)/third-party/openamp) ABSOLUTE_CFILES += $(wildcard $(OPENAMP_C_DIR)/lib/*.c \ $(OPENAMP_C_DIR)/lib/remoteproc/*.c \ diff --git a/third-party/sfud-1.1.0/src.mk b/third-party/sfud-1.1.0/src.mk index 7fa9e14276ed8e8f9f3f28236b32ceff5ce2f148..fbda9eb1c8ad4febd51ea8c0cf8bbac90e3f931c 100644 --- a/third-party/sfud-1.1.0/src.mk +++ b/third-party/sfud-1.1.0/src.mk @@ -10,7 +10,7 @@ ifdef CONFIG_USE_SFUD CSRCS_RELATIVE_FILES += $(wildcard ports/fqspi/*.c) endif -SFUD_RT_C_DIR = $(SDK_DIR)/third-party/sfud-1.1.0 +SFUD_RT_C_DIR = $(abspath $(SDK_DIR)/third-party/sfud-1.1.0) ABSOLUTE_CFILES += $(wildcard $(SFUD_RT_C_DIR)/src/*.c) diff --git a/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.c b/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.c index 4bddf0563561d94432b756fbb58878ff2813eba7..49b69908883d08b004035ea2775d02fb433c8e5e 100644 --- a/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.c +++ b/third-party/spiffs-0.3.7/ports/fqspi/fqspi_spiffs_port.c @@ -180,6 +180,7 @@ int FSpiffsQspiInitialize(FSpiffs *const instance) void FSpiffsQspiDeInitialize(FSpiffs *const instance) { memset(instance, 0, sizeof(FSpiffs)); + flash_instance = NULL; is_sfud_ready = FALSE; return; } diff --git a/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.c b/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.c index eabb61e68c5a26c5dcd2079818414d99ea54da7f..76c5123757bee01702e9dec88c557e6110041593 100644 --- a/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.c +++ b/third-party/spiffs-0.3.7/ports/fspim/fspim_spiffs_port.c @@ -40,9 +40,9 @@ /************************** Variable Definitions *****************************/ static boolean is_sfud_ready = FALSE; static const sfud_flash *flash_instance = NULL; -#if defined(CONFIG_TARGET_E2000D)||defined(CONFIG_TARGET_E2000Q) +#if defined(CONFIG_E2000Q_DEMO_BOARD) || defined(CONFIG_E2000D_DEMO_BOARD) static const fsize_t flash_id = SFUD_FSPIM2_INDEX; -#elif defined(CONFIG_TARGET_PHYTIUMPI) +#elif defined(CONFIG_FIREFLY_DEMO_BOARD) static const fsize_t flash_id = SFUD_FSPIM0_INDEX; #endif @@ -132,7 +132,6 @@ int FSpiffsSpimInitialize(FSpiffs *const instance) FSPIM_ERROR("little-fs already inited and mounted"); return FSPIFFS_SPIM_PORT_ALREADY_INITED; } - if ((TRUE == is_sfud_ready) || (NULL != flash_instance)) { FSPIM_ERROR("sfud already inited"); @@ -145,14 +144,12 @@ int FSpiffsSpimInitialize(FSpiffs *const instance) FSPIM_ERROR("sfud init failed: %d", sfud_ret); return FSPIFFS_SPIM_PORT_SFUD_INIT_FAILED; } - flash_instance = sfud_get_device(flash_id); if (NULL == flash_instance) { FSPIM_ERROR("Get sfud flash failed"); return FSPIFFS_SPIM_PORT_SFUD_INIT_FAILED; } - if ((flash_instance->chip.capacity < (instance->fs_addr + instance->fs_size)) || (FSPIFFS_LOG_BLOCK_SIZE % flash_instance->chip.erase_gran)) { @@ -185,6 +182,7 @@ int FSpiffsSpimInitialize(FSpiffs *const instance) void FSpiffsSpimDeInitialize(FSpiffs *const instance) { memset(instance, 0, sizeof(FSpiffs)); + flash_instance = NULL; is_sfud_ready = FALSE; return; } diff --git a/third-party/spiffs-0.3.7/src/spiffs_hydrogen.c b/third-party/spiffs-0.3.7/src/spiffs_hydrogen.c index 69e0c22d1be16b4a3e7c8b901a1421af48b2f7ea..a6929e349f60d322dd76f608c59cd91b857bd690 100644 --- a/third-party/spiffs-0.3.7/src/spiffs_hydrogen.c +++ b/third-party/spiffs-0.3.7/src/spiffs_hydrogen.c @@ -235,7 +235,7 @@ spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs if (res == SPIFFS_OK && (flags & (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) == (SPIFFS_O_CREAT | SPIFFS_O_EXCL)) { - // creat and excl and file exists - fail + // create and excl and file exists - fail res = SPIFFS_ERR_FILE_EXISTS; spiffs_fd_return(fs, fd->file_nbr); SPIFFS_API_CHECK_RES_UNLOCK(fs, res); diff --git a/tools/include.mk b/tools/include.mk index 5dac88d4c29b76d9ce86d13399d2e23eeaae94b4..d869c5bb42d7e870b445792cf9022fca89fe83f4 100644 --- a/tools/include.mk +++ b/tools/include.mk @@ -1,6 +1,11 @@ FREERTOS_SDK_DIR ?= $(SDK_DIR)/.. +# primary sdk dir, relative to standalone sdk +PRI_SDK_RELATIVE_DIR ?= ../ + +export PRI_SDK_RELATIVE_DIR + # drivers include $(FREERTOS_SDK_DIR)/drivers/include.mk