1、CAN 485相关理解
3、snprintf(写到哪里,写多少个,"格式化字符",变量) snprintf(buf,sizeof(temp),"%s",version);strncat(连接到哪里,连接谁,从哪里开始连接) strncat(buf,temp.sizeof(buf)-strlen(buf)-1);
4、结构体数组的使用和初始化Device_ST *dev_st = &devicezj_id-23;
5、与或非,异或,同或解决不了的变量取值问题,使用遍历移位 与操作 再取反
6、对于一个结构体,实例化是一个二维数组,比如DevInfo_md md_dev3MAX_DEV;
假设 MAX_DEV = 10,那么 md_dev3MAX_DEV 就是一个包含 3 行,每行 10 个 DevInfo_md 元素的数组。你可以通过 md_devi 访问某一行,也可以通过 md_devij 访问某一行的具体元素。
md_devi 是类型 DevInfo_mdMAX_DEV 的一维数组;
md_devij 是 DevInfo_md 类型的单个元素
md_devi访问的是这一行,一个类型,二维数组访问的是具体的某个元素
7、函数指针结构体的用法
8、开发商,物业,楼栋楼层 结构体指针的应用
如果是全局的结构体,创建很多的数组,会占用大量的全局空间内存,总10KB左右 数据量小,均匀连续
如果是局部结构体,占用栈区空间消耗,总40KB左右,但是访问比较快,不用考虑内存泄漏问题,性能好,代码简单
如果使用结构体指针创建,需要动态开辟内存空间, 总120KB左右,需要手动释放,开发复杂,但是节省内存空间,不会导致溢出 数据量大,不均匀
对于启动文件的堆栈空间,线程创建消耗栈区内存,虽然可能创建的线程很多,超过了栈区的总大小,但是实际使用并没有超过当前线程分配的栈空间大小
还有一些情况内存空间是动态调整的,但是最好还是遵循内存布局,使用指针不需要的时候释放空间,需要再用
另外访问的时候遍历也能少一些
9、冒泡,快速,插入,反转,斐波那契,质数
10、中断和事件,外部中断
11.在多个实时变化的数据中取出最大值
12.并发线程,多个时间线程同时异步执行,多个中继器同时执行不同的喷洒逻辑
状态机,消息队列,定时器
13.精通UART,SPI,IIC,USB,CAN 485常见的协议移植和驱动开发,并且示波器调信号,
14.编码器控制PWM,ADC传感器读取,
15.IAP升级,bootloader开发移植
16.rt_thread操作系统 OTA升级功能
17.rt_thread_mdelay打印部分,哪个线程在占用 线程耗时比较短的线程打印
18.对于数字类需要加U尾缀 然后移位操作 如果超过32位 1需要改成 (UINT64_C(1)) 所有的数字都要
19.事件集的处理
20.实时打印当前运行的线程名称
cpp
在void rt_schedule(void)中最后增加
#if DEBUG_TIME
static struct rt_thread *last=NULL;
if(last!=rt_current_thread)
{
last=rt_current_thread;
rt_kprintf("RUN:%s\r\n",
rt_current_thread->name);
}
#endif
/* enable interrupt */
rt_hw_interrupt_enable(level);
__exit:
return;
21.实时打印线程名称和delay时间
cpp
rt_err_t rt_thread_mdelay(rt_int32_t ms)
{
#if DEBUG_TIME
rt_thread_t thread;
thread = rt_thread_self();
if(ms > 0 && ms < 1000)
{
rt_kprintf("[DIRECT_MDELAY] th=%s ms=%d tick=%u\r\n",
thread != RT_NULL
? thread->name
: "null",
ms,
(unsigned int)rt_tick_get());
}
#endif
rt_tick_t tick;
tick = rt_tick_from_millisecond(ms);
return rt_thread_sleep(tick);
}
22.低功耗模式下让JLINKE一直保持连接
cpp
DBG_ConfigPeriph(DBG_SLEEP |
DBG_STOP |
DBG_IWDG_STOP |
DBG_WWDG_STOP,
ENABLE);
23.线程最好要统一处理,尽量减少线程的使用,增加局部函数体的调用,局部变量一定要初始化
24.当使用rt_thread_mdelay进行时间片切换的时候,其他外部触发需要准确下一步跳转到xx线程运行的处理,参考安定宝代码gpio点灯部分
随机bug原因:
1.边界问题 临界区
2.共享内存
3.全局变量多出修改
4.上行输入诊断
5.饱和,限幅值
6.溢出 泄露
7.锁范围释放
8中断嵌套优先级配置错误
9野指针、空指针访问
10未初始化局部变量
11看门狗使用不当
12Flash/EEPROM 擦写超时、写冲突
13内存对齐问题
软件设计规则:
□ 01. 我处理的是"当前状态",还是其实应该处理"状态变化"?
□ 02. 如果只允许触发一次,我有没有保存 last / handled?
□ 03. 多个 bool 能不能用 bitmask 表达得更清楚?
□ 04. if/else 是否已经多到应该改成状态机?
□ 05. 有没有为了等时间而阻塞本可继续运行的任务?
□ 06. 超时判断是否使用了统一的 tick/时间单位?
□ 07. 输入会不会抖?是否需要连续 N 次确认或迟滞?
□ 08. 中断里是否做了 printf、解析、循环、阻塞等重工作?
□ 09. 生产数据和消费数据速度不同,是否需要队列/环形缓冲区?
□ 10. 共享变量是否存在多个写者?能否明确唯一 owner?
□ 11. 多字段读取是否可能出现"一半新、一半旧"?
□ 12. 数组下标、长度、地址、枚举是否做了范围检查?
□ 13. "0 / -1 / 0xFF"到底是正常值还是故障值?有效性是否应独立?
□ 14. 故障应该自动恢复,还是必须人工 reset?
□ 15. 数值计算、计数器、乘法有没有溢出风险?
□ 16. 通信失败后是有限重试,还是无脑高频重发?
需求一实现一风险点一查手册一做实验一总结一个模型。