dvd1478

  • 2019-03-24
  • 发表了主题帖: 【NXP Rapid IoT评测】FreeRTOS调试方法(任务执行情况输出)

              NXP Rapid IoT源代码中很丰富,虽然知道使用FreeRTOS的但是代码的嵌套异常的复杂,对分析起来带来了困难。所以想通过FreeRTOS自身的vTaskList与 vTaskGetRunTimeStats 输出自身运行任务的情况          效果如下: 上面截图中打印出来的任务状态字母 B, R, D, S 对应如下含义: #define tskBLOCKED_CHAR         ( 'B' )    任务阻塞 #define tskREADY_CHAR              ( 'R' )    任务就绪 #define tskDELETED_CHAR          ( 'D' )    任务删除 #define tskSUSPENDED_CHAR     ( 'S' )    任务挂起 另外要注意剩余栈的单位是 word,即 4 字节。 一、修改宏 .\RapidIot_Base\middleware\wireless\framework\Common\rtos\FreeRTOS\config\FreeRTOSConfig.h 修改以下宏 /* Run time and task stats gathering related definitions. */ #define configUSE_TRACE_FACILITY                                   1 #define configGENERATE_RUN_TIME_STATS                           1 #define configUSE_STATS_FORMATTING_FUNCTIONS           1 /* Ensure stdint is only used by the compiler, and not the assembler. */ #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)   #include   extern volatile uint32_t ulHighFrequencyTimerTicks; #endif #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()  (ulHighFrequencyTimerTicks = 0ul) #define portGET_RUN_TIME_COUNTER_VALUE()           ulHighFrequencyTimerTicks复制代码 二、添加以下代码 /* ********************************************************************************************************* * *        模块名称 : FreeRTOS任务信息 *        文件名称 : *        版    本 : V1.0 *        说    明 : 为了获取FreeRTOS的任务信息,需要创建一个定时器,这个定时器的时间基准精度要高于 *              系统时钟节拍。这样得到的任务信息才准确。 *              本文件提供的函数仅用于测试目的,切不可将其用于实际项目,原因有两点: *               1. FreeRTOS的系统内核没有对总的计数时间做溢出保护。 *               2. 定时器中断是50us进入一次,比较影响系统性能。 *              -------------------------------------------------------------------------------------- *              本文件使用的是32位变量来保存50us一次的计数值,最大支持计数时间: *              2^32 * 50us / 3600s = 59.6分钟。使用中测试的任务运行计数和任务占用率超过了59.6分钟将不准确。 * * ********************************************************************************************************* */ #include #include "fsl_pit.h" #include "clock_config.h" #include "fsl_os_abstraction.h" #include "fsl_os_abstraction_free_rtos.h" //#include "cmsis_os.h" #include "FreeRTOS.h" #include "task.h" #include "timers.h" #include "queue.h" #include "semphr.h" #include "event_groups.h" #include "shell.h" #include "atmosphere_platform.h" /* 定时器频率,50us一次中断 */ #define  timerINTERRUPT_FREQUENCY        20000 /* 中断优先级 */ #define  timerHIGHEST_PRIORITY                2 /* 被系统调用 */ volatile uint32_t ulHighFrequencyTimerTicks = 0UL; static int8_t shell_cmdTaskInfo(uint8_t argc, char * argv[]); const cmd_tbl_t CommandTask_Ver = {       .name = "taskinfo",         .maxargs = 2,         .repeatable = 1,         .cmd = shell_cmdTaskInfo,         .usage = "print FreeRTOS Info ", #if SHELL_USE_AUTO_COMPLETE         .complete = NULL, #endif         .help = NULL }; static int8_t shell_cmdTaskInfo(uint8_t argc, char * argv[]) {     char* pcWriteBuffer=NULL;     pcWriteBuffer = (char*) ATMO_Malloc(512);     if (pcWriteBuffer)     {         shell_write("=================================================\r\n");         shell_write("Task            State  Prio  ReStack  Num\r\n");         vTaskList((char *) pcWriteBuffer);         shell_writeN(pcWriteBuffer,strlen(pcWriteBuffer));         shell_write("\r\nTask            Count           Usage\r\n");         vTaskGetRunTimeStats((char *) pcWriteBuffer);         shell_writeN(pcWriteBuffer,strlen(pcWriteBuffer));         ATMO_Free(pcWriteBuffer);     } else {         shell_write("FreeRtos TaskInfo Error\r\n");     }     return CMD_RET_SUCCESS; } /* ********************************************************************************************************* *        函 数 名: vSetupTimerTest *        功能说明: 创建定时器 *        形    参: 无 *        返 回 值: 无 ********************************************************************************************************* */ void vAFreeRtosTaskInfoInit(void) {     /* Structure of initialize PIT */     pit_config_t pitConfig;     /*      * pitConfig.enableRunInDebug = false;      */     PIT_GetDefaultConfig(&pitConfig);     /* Init pit module */     PIT_Init(PIT, &pitConfig);     /* Set timer period for channel 0 */     PIT_SetTimerPeriod(PIT, kPIT_Chnl_0,             USEC_TO_COUNT(50U, CLOCK_GetFreq(kCLOCK_BusClk)));     /* Enable timer interrupts for channel 0 */     PIT_EnableInterrupts(PIT, kPIT_Chnl_0, kPIT_TimerInterruptEnable);     /* Enable at the NVIC */     EnableIRQ(PIT0_IRQn);     shell_register_function((cmd_tbl_t *)&CommandTask_Ver); } /* ********************************************************************************************************* *        函 数 名: PIT0_IRQHandler *        功能说明: PIT0中断服务程序。 *        形    参: 无 *        返 回 值: 无 ********************************************************************************************************* */ void PIT0_IRQHandler(void) {     /* Clear interrupt flag.*/     PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, kPIT_TimerFlag);     ulHighFrequencyTimerTicks++; } /********************************************* (END OF FILE) *********************************/ 复制代码 调用初始化函数void vAFreeRtosTaskInfoInit(void),然后通过串口输出 taskinfo,就能输出相应的任务情况 通过上述的调试,获取相应的创建任务的情况 以及相关的任务函数 分别如下: 1、 .\RapidIot_Base\middleware\wireless\framework\OSAbstraction\Source\fsl_os_abstraction_free_rtos.c int main (void) 创建 startup_task 任务 2、 .\RapidIot_Base\rtos\freertos\Source\tasks.c void vTaskStartScheduler( void )创建  IDLE  任务 3、 .\RapidIot_Base\rtos\freertos\Source\timers.c BaseType_t xTimerCreateTimerTask( void ) 创建 prvTimerTask任务 4、 .\app_src\app_emwin.c void emWinTaskInit(void)创建  emWinTask  任务 5、 .\RapidIot_Base\middleware\wireless\framework\SerialManager\Source\SerialManager.c void SerialManager_Init( void ) 创建 SerialManagerTask 任务 6、 .\RapidIot_Base\middleware\wireless\framework\TimersManager\Source\TimersManager.c void TMR_Init(void)  创建 TMR_Task任务 7、 .\RapidIot_Base\middleware\wireless\framework\SerialManager\Source\USB_VirtualCom\virtual_com.c void* VirtualCom_Init(uint8_t param)创建  USB_DeviceTask任务 8、 .\gpio\gpio_mk64f.c ATMO_GPIO_Status_t ATMO_MK64F_GPIO_Init(ATMO_DriverInstanceData_t *instance) 创建 ATMO_MK64F_GPIO_RXQueueChecker  ATMO_MK64F_GPIO_ButtonResetChecker任务 9、 .\interval\interval_mk64f.c ATMO_INTERVAL_Status_t ATMO_MK64F_INTERVAL_Init(ATMO_DriverInstanceData_t *instance) ATMO_INTERVAL_Status_t ATMO_MK64F_INTERVAL_AddCallbackInterval(ATMO_DriverInstanceData_t *instance, ATMO_Callback_t cb, unsigned int interval, ATMO_INTERVAL_Handle_t *intervalHandle) 创建 intervalTask 任务 此内容由EEWORLD论坛网友dvd1478原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-03-17
  • 发表了主题帖: 【NXP Rapid IoT评测】I2C程序小bug

    上一篇 解决了I2C死锁解除的方法, 【NXP Rapid IoT评测】触摸按键没有反应——I2C死锁解除方法 http://bbs.eeworld.com.cn/forum. ... &fromuid=194541。 但是总线上挂载的外设多时,有时会遇到外设失灵的情况,后来深入分析代码,出现问题在于 ATMO_Platform_I2C_Master_Transfer 这个函数上 static ATMO_I2C_Status_t ATMO_Platform_I2C_Master_Transfer(                 i2c_direction_t direction, kI2C_Blocking_t blocking, uint32_t instance,                 uint16_t slaveAddress, const uint8_t* cmdBytes, uint16_t numCmdBytes,                 uint8_t* dataBytes, uint16_t numDataBytes) {         status_t platformStatus = kStatus_Fail;         i2c_master_transfer_t masterStructure;         uint32_t cmd;         if (instance > MK64F_NUM_I2C_INSTANCES) {                 return ATMO_I2C_Status_NotSupported;         }         if (ATMO_Platform_I2C_Peripheral[instance].operatingMode                         == ATMO_I2C_OperatingMode_Slave) {                 return ATMO_I2C_Status_Invalid;         }         if (numCmdBytes > 4) {                 return ATMO_I2C_Status_NotSupported;         }         if ((dataBytes == NULL) || (numDataBytes == 0)) {                 return ATMO_I2C_Status_Invalid;         }         // if either cmdBytes or numCmdBytes is null/zero then set both to null/zero         if (cmdBytes == NULL) {                 numCmdBytes = 0;         } else if (numCmdBytes == 0) {                 cmdBytes = NULL;         }         if (numCmdBytes == 1) {                 cmd = cmdBytes[0];         } else if (numCmdBytes == 2) {                 cmd = (cmdBytes[0] transfer.data - xferCount;                         masterXfer.dataSize = xferCount;                         if (callback != NULL) {                                 callback(&masterXfer, userData);                         }                 } else {                         if (callback != NULL) {                                 callback(&masterXfer, userData);                         }                 }         }         /* Signal transfer failure when received any other status. */         if ((status == kStatus_I2C_Nak) || (status == kStatus_I2C_Addr_Nak)                         || (status == kStatus_I2C_ArbitrationLost)                         || (status == kStatus_I2C_Timeout)) {                 nakFlag[instance] = true;         } }复制代码 实现阻塞为读写。 同时提供一个扫描I2C总线上设备的代码 ATMO_I2C_Status_t ATMO_I2C_Scan(ATMO_DriverInstanceHandle_t instance) {         uint8_t cmdBuf[2]={0};         uint8_t readBuf[1]={0};         uint8_t slaveAddress=0;         ATMO_I2C_Status_t status=ATMO_I2C_Status_Unknown;         ATMO_PLATFORM_DebugUsbPrint("Driver On I2C%d Line:\r\n    ",instance);         for(slaveAddress= 0x00;slaveAddress

  • 2019-03-16
  • 加入了学习《优化变压器设计来改进反激式变换器的效率和EMI性能》,观看 1.5 减小反激式变压器的EMI性能

  • 加入了学习《优化变压器设计来改进反激式变换器的效率和EMI性能》,观看 1.4 反激式变压器的漏感和嵌位电压

  • 加入了学习《优化变压器设计来改进反激式变换器的效率和EMI性能》,观看 1.3 反激式变压器的铜损

  • 加入了学习《优化变压器设计来改进反激式变换器的效率和EMI性能》,观看 1.2 反激式变压器的磁心损耗?

  • 加入了学习《优化变压器设计来改进反激式变换器的效率和EMI性能》,观看 1.1 反激式变压器的概论

  • 加入了学习《工业及汽车系统的低EMI电源变换器设计》,观看 EMI 优化技巧小结

  • 加入了学习《工业及汽车系统的低EMI电源变换器设计》,观看 通过增加 EMI 滤波器有效降低 EMI

  • 加入了学习《工业及汽车系统的低EMI电源变换器设计》,观看 通过频率抖动有效降低 EMI

  • 加入了学习《工业及汽车系统的低EMI电源变换器设计》,观看 通过控制开关点的 Slew Rate 有效降低 EMI

  • 加入了学习《工业及汽车系统的低EMI电源变换器设计》,观看 通过优化 PCB layout 有效降低 EMI

  • 加入了学习《工业及汽车系统的低EMI电源变换器设计》,观看 降低开关电源EMI干扰的方法

  • 加入了学习《工业及汽车系统的低EMI电源变换器设计》,观看 工业及汽车运用DCDC的主要特点

  • 加入了学习《工业及汽车系统的低EMI电源变换器设计》,观看 课程概览

  • 加入了学习《采用热棒包装减少 EMI 和收缩解决方案尺寸》,观看 采用热棒包装减少EMI和收缩解决方案尺寸

  • 2019-03-15
  • 加入了学习《功率变换器电磁干扰及其相关电磁基础》,观看 2.8 共模滤波电感器

  • 2019-03-10
  • 回复了主题帖: 恩智浦Rapid IoT套件有奖评测颁奖啦~期待2019年江湖再见,一起成长

    恭喜各位获奖者,惭愧了,到后边没有时间完成当时的评测计划。至前的失败在于太过依赖Rapid IOT Studio官网https://rapid-iot-studio.nxp.com。那网站实在太难登录,同时也低评了项目的容易性,高估了自己的能力。看了网友的测试,突然有了思路,其实Rapid IOT Studio就是一个原理性的设计,更多的情况还得通过离线性优化代码。不想没有做出什么东西,就退了,故申请多使用两个月,最终目标用离线型MCUXpresso IDE开发一个小游戏。每周小目标是发布一篇关于Rapid IoT套件的开发分享。 3.10分享【NXP Rapid IoT评测】触摸按键没有反应——I2C死锁解除方法 http://bbs.eeworld.com.cn/forum. ... &fromuid=194541

  • 发表了主题帖: 【NXP Rapid IoT评测】触摸按键没有反应——I2C死锁解除方法

    NXP Rapid IoT  上用I2C1上挂了很多外设, I2C1: Sensors + Touch: FXOS8700, FXAS21002, MPL3115, ENS210, TSL25711, CCS811 (behind I2C switch), SX9500 I2C2: after I2C switch (...NTAG_I2C_EN): NT3H2211, A1006, A71 而且在开发过程中不何避免的复位重启Rapid IoT,造成了I2C时序混乱,同时又由于电池供电,而且I2C上所有设置并不是都全可以进行掉电或者硬件复件。 体现的现象   触摸按键没有反应,传感器没有数据,信号现象 SCL为高,SDA一直为低 死锁产生的原因分析如下:      在正常情况下,I2C总线协议能够保证总线正常的读写操作。但是,当I2C主设备异常复位时(看门狗动作,板上电源异常导致复位芯片动作,手动按钮复位等等)有可能导致I2C总线死锁产生。下面详细说明一下总线死锁产生的原因。       在I2C主设备进行读写操作的过程中.主设备在开始信号后控制SCL产生8个时钟脉冲,然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平。如果这个时候主设备异常复位,SCL就会被释放为高电平。此时,如果从设备没有复位,就会继续I2C的应答,将SDA一直拉为低电平,直到SCL变为低电平,才会结束应答信号。而对于I2C主设备来说.复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为I2C总线被占用,会一直等待SCL和SDA信号变为高电平。这样,I2C主设备等待从设备释放SDA信号,而同时I2C从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,I2C总线进人一种死锁状态。同样,当I2C进行读操作,I2C从设备应答后输出数据,如果在这个时刻I2C主设备异常复位而此时I2C从设备输出的数据位正好为0,也会导致I2C总线进入死锁状态。 解锁方法如下: (1) 尽量选用带复位输人的I2C从器件。 (2) 将所有的从I2C设备的电源连接在一起,通过MOS管连接到主电源,而MOS管的导通关断由I2C主设备来实现。 (3) 在I2C从设备设计看门狗的功能。 (4) 在I2C主设备中增加I2C总线恢复程序。每次I2C主设备复位后,如果检测到SDA数据线被拉低,则控制I2C中的SCL时钟线产生9个时钟脉冲(针对8位数据的情况),这样I2C从设备就可以完成被挂起的读操作,从死锁状态中恢复过来。 (5) 在I2C总线上增加一个额外的总线恢复设备。 (6) 在I2C上串人一个具有死锁恢复的I2C缓冲器,如Linear公司的LTC4307。 硬件也设置好,而且并非每一个设备都满足上面的条件,只能选择方法(4),具体体现的代码如下: static void i2c_release_bus_delay(void) { #if 0 #define I2C1_RELEASE_BUS_COUNT 200U     uint32_t i = 0;     for (i = 0; i < I2C1_RELEASE_BUS_COUNT; i++)     {         __NOP();     } #else     App_WaitUsec(100); #endif } void BOARD_I2C1_ConfigurePins(void) {     /* Port C Clock Gate Control: Clock enabled */     CLOCK_EnableClock(kCLOCK_PortC);     const port_pin_config_t portc10_pinC7_config = {/* Internal pull-up resistor is enabled */                                                     kPORT_PullUp,                                                     /* Fast slew rate is configured */                                                     kPORT_FastSlewRate,                                                     /* Passive filter is disabled */                                                     kPORT_PassiveFilterDisable,                                                     /* Open drain is enabled */                                                     kPORT_OpenDrainEnable,                                                     /* Low drive strength is configured */                                                     kPORT_LowDriveStrength,                                                     /* Pin is configured as I2C1_SCL */                                                     kPORT_MuxAlt2,                                                     /* Pin Control Register fields [15:0] are not locked */                                                     kPORT_UnlockRegister};     /* PORTC10 (pin C7) is configured as I2C1_SCL */     PORT_SetPinConfig(PORTC, 10U, &portc10_pinC7_config);     const port_pin_config_t portc11_pinB7_config = {/* Internal pull-up resistor is enabled */                                                     kPORT_PullUp,                                                     /* Fast slew rate is configured */                                                     kPORT_FastSlewRate,                                                     /* Passive filter is disabled */                                                     kPORT_PassiveFilterDisable,                                                     /* Open drain is enabled */                                                     kPORT_OpenDrainEnable,                                                     /* Low drive strength is configured */                                                     kPORT_LowDriveStrength,                                                     /* Pin is configured as I2C1_SDA */                                                     kPORT_MuxAlt2,                                                     /* Pin Control Register fields [15:0] are not locked */                                                     kPORT_UnlockRegister};     /* PORTC11 (pin B7) is configured as I2C1_SDA */     PORT_SetPinConfig(PORTC, 11U, &portc11_pinB7_config); } void I2C1_ReleaseBus(void) {     uint8_t i = 0;     gpio_pin_config_t pin_config;     port_pin_config_t i2c_pin_config = {0};     /* Config pin mux as gpio */     i2c_pin_config.pullSelect = kPORT_PullUp;     i2c_pin_config.mux = kPORT_MuxAsGpio;     pin_config.pinDirection = kGPIO_DigitalOutput;     pin_config.outputLogic = 1U;     CLOCK_EnableClock(kCLOCK_PortC);     PORT_SetPinConfig(BOARD_INITPINS_I2C1_SCL_PORT, BOARD_INITPINS_I2C1_SCL_PIN, &i2c_pin_config);     PORT_SetPinConfig(BOARD_INITPINS_I2C1_SDA_PORT, BOARD_INITPINS_I2C1_SDA_PIN, &i2c_pin_config);     GPIO_PinInit(BOARD_INITPINS_I2C1_SCL_PORT, BOARD_INITPINS_I2C1_SCL_PIN, &pin_config);     GPIO_PinInit(BOARD_INITPINS_I2C1_SDA_PORT, BOARD_INITPINS_I2C1_SDA_PIN, &pin_config);     /* Drive SDA low first to simulate a start */     GPIO_PinWrite(BOARD_INITPINS_I2C1_SDA_PORT, BOARD_INITPINS_I2C1_SDA_PIN, 0U);     i2c_release_bus_delay();     /* Send 9 pulses on SCL and keep SDA high */     for (i = 0; i < 9; i++)     {         GPIO_PinWrite(BOARD_INITPINS_I2C1_SCL_PORT, BOARD_INITPINS_I2C1_SCL_PIN, 0U);         i2c_release_bus_delay();         GPIO_PinWrite(BOARD_INITPINS_I2C1_SDA_PORT, BOARD_INITPINS_I2C1_SDA_PIN, 1U);         i2c_release_bus_delay();         GPIO_PinWrite(BOARD_INITPINS_I2C1_SCL_PORT, BOARD_INITPINS_I2C1_SCL_PIN, 1U);         i2c_release_bus_delay();         i2c_release_bus_delay();     }     /* Send stop */     GPIO_PinWrite(BOARD_INITPINS_I2C1_SCL_PORT, BOARD_INITPINS_I2C1_SCL_PIN, 0U);     i2c_release_bus_delay();     GPIO_PinWrite(BOARD_INITPINS_I2C1_SDA_PORT, BOARD_INITPINS_I2C1_SDA_PIN, 0U);     i2c_release_bus_delay();     GPIO_PinWrite(BOARD_INITPINS_I2C1_SCL_PORT, BOARD_INITPINS_I2C1_SCL_PIN, 1U);     i2c_release_bus_delay();     GPIO_PinWrite(BOARD_INITPINS_I2C1_SDA_PORT, BOARD_INITPINS_I2C1_SDA_PIN, 1U);     i2c_release_bus_delay();     BOARD_I2C1_ConfigurePins(); }复制代码 初始上时钟后,就可以调用上述代码。 完整代码, 替换  工程文件\RapidIot_Base\board\board.c 此内容由EEWORLD论坛网友dvd1478原创,如需转载或用于商业用途需征得作者同意并注明出处

  • 2019-01-23
  • 发表了主题帖: 【NXP Rapid IoT评测】为Rapid添加USB模拟串口功能

    NXP Rapid IoT  SLN-RPK-NODE还有一个痛点就是虽然扩展板进能进行调试,在没有扩展板的情况下,不能调试,无疑添加了调试的难度。幸亏还有一个有用的接口,就是USB,这次主要的功能是为其添加Virtual com功能 由于NXP Rapid IoT 并没有USB的模块,只能采用离线编译的方式,如下所示: 【NXP Rapid IoT评测】离线编译与测试总结 http://bbs.eeworld.com.cn/forum. ... &fromuid=194541 (出处: 电子工程世界-论坛) 工程文件如下: 模拟串口驱动如下: 烧写方法,与NXP Rapid IoT 原来的方法一样 SW3按下  SW5复位 复制BIN文件,就可以 重新热插拔后,手动更新驱动, 效果如下所示 关键文件如下所示: 在main_test添加以下代码就可以运行 此内容由EEWORLD论坛网友dvd1478原创,如需转载或用于商业用途需征得作者同意并注明出处

最近访客

< 1/2 >

统计信息

已有80人来访过

  • 芯币:1965
  • 好友:--
  • 主题:31
  • 回复:141
  • 课时:--
  • 资源:10

留言

你需要登录后才可以留言 登录 | 注册


bmyuan 2018-4-20
期待成为朋友   Q   158356574     我想了解一些电子方面的东西,还请相教
查看全部