像 RV1103 ,F1C100S 这种,性能够用,内存也够大,但原厂资料不够开放,提供的是 Linux ,我想要跑 RTOS 。
]]>结果 Chatgpt 告诉我,我的想法是正确的,可行的 Gemini 告诉我,我的想法是错误的。
]]>在 cubeide 或 keil 不出现错误
j-link 可以正常下载运行。
新手求大佬指导
相关配置
报错
]]>could not connect (error 138): ϵͳ ͼ ϲ ϲ ϵ Ŀ¼
You can't do that when your target isexec' "monitor" command not supported by this target. You can't do that when your target is
exec' 上传完成,但存在问题 monitor reset "monitor" command not supported by this target.
stm32F030c8 的闪存有 64KB ,为了方便调试,mcuboot 编译完了有 20 多 KB ,于是我就按照 24KB + 20KB + 20KB 给闪存分为了 boot_partition + slot0_partition + slot1_partition ,三个分区。后面调试通了打算把 boot 分区优化到 16KB 。
mcuboot 直接从 github 上 pull 了最新的代码,然后加了一个 custom 的 board 进去。为了跑通流程,我在 prj.conf 中把:
之后就是 west build ,然后 upload 到板子上,开机上电,串口正常显示 mcuboot 启动。
之后,写了一个简单的闪灯应用,用了 platform.io + zephyr ,同一套板子配置文件,先不分区直接 upload ,确认了程序能跑。
然后按照说明,
一波操作之后生成了带签名的 firmware.elf 。上传到板子上发现不运行。
生成的 firmware 是
Printing content of signed image: firmware.mcuboot.bin #### Image header (offset: 0x0) ############################ magic: 0x96f3b83d load_addr: 0x0 hdr_size: 0x200 protected_tlv_size: 0x0 img_size: 0x3d92 flags: 0x0 version: 0.0.0+0 ############################################################ #### Payload (offset: 0x200) ############################### | | | FW image (size: 0x3d92 Bytes) | | | ############################################################ #### TLV area (offset: 0x3f92) ############################# magic: 0x6907 area size: 0x150 --------------------------------------------- type: SHA256 (0x10) len: 0x20 data: 0x90 0x7f 0xa3 0xbc 0x5d 0xdc 0x34 0xa8 0xa9 0x06 0xa4 0x64 0x5d 0x73 0x79 0x24 0xea 0x62 0x6e 0x6e 0x37 0x99 0x5c 0x72 0x61 0x85 0xf1 0xda 0x45 0x72 0x87 0xaa --------------------------------------------- type: KEYHASH (0x1) len: 0x20 data: 0xfc 0x57 0x01 0xdc 0x61 0x35 0xe1 0x32 0x38 0x47 0xbd 0xc4 0x0f 0x04 0xd2 0xe5 0xbe 0xe5 0x83 0x3b 0x23 0xc2 0x9f 0x93 0x59 0x3d 0x00 0x01 0x8c 0xfa 0x99 0x94 --------------------------------------------- type: RSA2048 (0x20) len: 0x100 data: 0x67 0x30 0x0a 0xf8 0xee 0xad 0xba 0xbf 0xac 0x22 0x6d 0x3a 0xac 0x76 0x9f 0x60 0xb0 0x2c 0x3f 0x5e 0x4d 0xf7 0x3f 0x0d 0x9b 0x24 0xbe 0x4a 0x70 0xa4 0x44 0x08 0x7c 0xe7 0x27 0xce 0x0d 0xca 0x97 0x18 0x3c 0xc3 0x15 0xbe 0xb0 0x0b 0xb5 0xf1 0x10 0xff 0x84 0x59 0xca 0xc2 0x29 0x42 0xf0 0x8c 0xbb 0xd1 0x38 0xe5 0x6c 0xeb 0xde 0xf4 0x1f 0xa0 0x8f 0xde 0x0b 0xe2 0x23 0x3e 0x2e 0xd6 0xcb 0xf6 0x22 0x0d 0x54 0x88 0xf3 0x7e 0x86 0xd0 0xb7 0x7d 0x9d 0x75 0x8a 0xa9 0xa0 0x73 0xb6 0xee 0x9a 0x6b 0x80 0xb9 0xd7 0x87 0x65 0x3c 0x89 0x3b 0x90 0xd2 0x0a 0xf1 0xcb 0xe8 0x4b 0x73 0xbd 0xe2 0x05 0x75 0x35 0x8c 0xc0 0xa0 0x38 0x26 0x10 0xac 0x07 0xf3 0xae 0x58 0xa0 0x8e 0x64 0x8c 0x06 0x76 0x15 0x24 0xe5 0xeb 0x9a 0x56 0x97 0x91 0x99 0xa4 0x18 0xd9 0xd8 0x8a 0xaa 0xcb 0x73 0x07 0xd0 0xc5 0x96 0x79 0x95 0xa1 0xf3 0xec 0x21 0xf0 0xae 0xa5 0x8e 0x46 0xb8 0xdd 0x09 0x0b 0xbc 0x6f 0x4c 0xfe 0xa8 0x91 0xfc 0xdb 0x10 0x71 0x3a 0x16 0x5f 0xd2 0xf1 0x49 0x3c 0x24 0x58 0x8f 0xc5 0x82 0xc3 0x6c 0xf5 0xe9 0x16 0x08 0xb3 0x35 0x30 0x38 0x08 0x43 0x27 0x25 0x08 0x61 0x36 0xb8 0x83 0x04 0xac 0xae 0x94 0x8d 0x27 0x31 0x61 0x6b 0x11 0x1d 0xa2 0x0f 0x48 0xd9 0x0e 0x5c 0x27 0x3f 0x3c 0x19 0xa2 0x38 0xe8 0x90 0x32 0x50 0xd7 0xdd 0x4d 0x9d 0xf5 0x2d 0xa5 0xec 0xed 0xf6 0x04 0x51 0x91 0xf3 0xe8 0xc8 ############################################################ #### End of Image ######################################### dumpinfo has run successfully
分区信息是:
flash_primary: base_address: 0x08000000 size: 64K # Bootloader mcuboot: address: 0x08000000 size: 24K # Application slot 0 image_0: address: 0x08006000 size: 20K # Upgrade slot image_1: address: 0x0800b000 size: 20K
启动时候串口输出:
*** Booting MCUboot v2.1.0-rc1-271-gc8470fb145f8 *** *** Using Zephyr OS build v4.1.0-1989-g1f9f4c8cee02 *** MCUBoot I: Starting bootloader D: Non-optimal sector distribution, slot0 has 18 usable sectors (20 assigned) but slot1 has 20 assigned I: Prim ary image: magic=good, swap_type=0x1, copy_dOne=0x3, image_ok=0x1 I: Secondary image: magic=unset, swap_type=0x1, copy_dOne=0x3, image_ok=0x3 I: Boot source: primary slot I: Image index: 0, Swap type: none I: Bootloader chainload address offset: 0x6000 I: Image version: v0.0.0 I: Jumping to the first image slot�*
可以看到它 mcuboot 正确识别到了 image ,但是在跳转到 image 的那一刻就挂掉了。
大家指点指点。
]]>亮度控制一般有两种方案,DC 调光和 PWM 调光。
但是某些奇怪的单片机设计直接把 TFT 屏的背光灯绑定在电源上,所以你只能开关背光,不能控制电压;所以只能被迫使用 PWM 调光。
然而对于单片机/RTOS 来说,每个 tick 都花一部分性能在控制方面可能有比较大的性能损耗,加上如果设备是无线电相关的话,PWM 带来的噪音可能会辐射到无线电部分导致未知的结果,所以只能采取第三种方案:伪颜色。
本质上 ILI9341 IC 的驱动当中是一个像素点一个像素点地画图
void lcd_write_pixel(ui::Color pixel) { lcd_write_data(pixel.v); }
这就相当简单了,直接把颜色通过浮点运算化为更“黑”的颜色即可实现“伪”亮度控制
void darken_color(ui::Color& pixel, float darken_level) { uint16_t r = (pixel.v >> 11) & 0x1F; uint16_t g = (pixel.v >> 5) & 0x3F; uint16_t b = pixel.v & 0x1F; r = static_cast<uint16_t>(r / darken_level); // darken g = static_cast<uint16_t>(g / darken_level); b = static_cast<uint16_t>(b / darken_level); pixel.v = (r << 11) | (g << 5) | b; // combine back }
但是浮点运算在单片机上相当慢,最后出来而结果可以用,但是渲染速度肉眼可见的下降。最后我的方案是损失一些调控精度,用移位运算代替浮点运算
void darken_color(ui::Color& pixel, uint8_t darken_level_shift) { // TODO: 1. do we need edge control? // currently didn't see and issue without edge control // but maybe hurts screen hardware without one? // TODO: 2. de-color mode for accessibility // TODO: 3. high contrast mode for accessibility uint16_t r = (pixel.v >> 11) & 0x1F; // extract uint16_t g = (pixel.v >> 5) & 0x3F; uint16_t b = pixel.v & 0x1F; r = r >> darken_level_shift; g = g >> darken_level_shift; b = b >> darken_level_shift; pixel.v = (r << 11) | (g << 5) | b; }
其中 darken_level_shift 是一个 uint8,0 代表 100%亮度,1 代表 50%亮度,以此类推
最后出来的结果终于可以用了:
void lcd_write_pixels(ui::Color pixel, size_t n) { if (get_dark_cover()) { darken_color(pixel, get_brightness()); // Darken }
void lcd_write_pixels_unrolled8(ui::Color pixel, size_t n) { if (get_dark_cover()) { darken_color(pixel, get_brightness()); // Darken }
摄像头是岭雁科技的 LYC40-PTZ ,经拆机确认 SoC 是君正的 T31N ,CMOS 是 sc2335 ,应该可以支持 OpenIPC ,所以用 ttl 连接后按照网上一些教程照葫芦画瓢准备进 u-boot 刷机。
启动日志如下:
U-Boot SPL 2013.07 (Nov 23 2020 - 17:19:58) Timer init CLK stop PLL init pll_init:366 pll_cfg.pdiv = 10, pll_cfg.h2div = 5, pll_cfg.h0div = 5, pll_cfg.cdiv = 1, pll_cfg.l2div = 2 nf=118 nr = 1 od0 = 1 od1 = 2 cppcr is 07605100 CPM_CPAPCR 0750510d nf=100 nr = 1 od0 = 1 od1 = 2 cppcr is 06405100 CPM_CPMPCR 0640510d nf=100 nr = 1 od0 = 1 od1 = 2 cppcr is 06405100 CPM_CPVPCR 0640510d cppcr 0x9a7b5510 apll_freq 1404000000 mpll_freq 1200000000 vpll_freq = 1200000000 ddr sel mpll, cpu sel apll ddrfreq 600000000 cclk 1404000000 l2clk 702000000 h0clk 240000000 h2clk 240000000 pclk 120000000 CLK init SDRAM init sdram init start ddr_inno_phy_init ..! phy reg = 0x00000007, CL = 0x00000007 ddr_inno_phy_init ..! 11: 00000004 ddr_inno_phy_init ..! 22: 00000006 ddr_inno_phy_init ..! 33: 00000006 REG_DDR_LMR: 00000210 REG_DDR_LMR: 00000310 REG_DDR_LMR: 00000110 REG_DDR_LMR, MR0: 00f73011 T31_0x5: 00000007 T31_0x15: 0000000c T31_0x4: 00000000 T31_0x14: 00000002 INNO_TRAINING_CTRL 1: 00000000 INNO_TRAINING_CTRL 2: 000000a1 T31_cc: 00000003 INNO_TRAINING_CTRL 3: 000000a0 T31_118: 0000003c T31_158: 0000003c T31_190: 0000001f T31_194: 0000001e jz-04 : 0x00000051 jz-08 : 0x000000a0 jz-28 : 0x00000024 DDR PHY init OK INNO_DQ_WIDTH :00000003 INNO_PLL_FBDIV :00000014 INNO_PLL_PDIV :00000005 INNO_MEM_CFG :00000051 INNO_PLL_CTRL :00000018 INNO_CHANNEL_EN :0000000d INNO_CWL :00000006 INNO_CL :00000007 DDR Controller init DDRC_STATUS 0x80000001 DDRC_CFG 0x0a288a40 DDRC_CTRL 0x0000011c DDRC_LMR 0x00400008 DDRC_DLP 0x00000000 DDRC_TIMING1 0x040e0806 DDRC_TIMING2 0x02170707 DDRC_TIMING3 0x2007051e DDRC_TIMING4 0x1a240031 DDRC_TIMING5 0xff060405 DDRC_TIMING6 0x32170505 DDRC_REFCNT 0x00f2e701 DDRC_MMAP0 0x000020fc DDRC_MMAP1 0x00002400 DDRC_REMAP1 0x03020d0c DDRC_REMAP2 0x07060504 DDRC_REMAP3 0x0b0a0908 DDRC_REMAP4 0x0f0e0100 DDRC_REMAP5 0x13121110 DDRC_AUTOSR_EN 0x00000000 sdram init finished SDRAM init ok board_init_r image entry point: 0x80100000 U-Boot 2013.07 (Nov 23 2020 - 17:19:58) Board: ISVP (Ingenic XBurst T31 SoC) DRAM: 64 MiB Top of RAM usable for U-Boot at: 84000000 Reserving 445k for U-Boot at: 83f90000 Reserving 32832k for malloc() at: 81f80000 Reserving 32 Bytes for Board Info at: 81f7ffe0 Reserving 124 Bytes for Global Data at: 81f7ff64 Reserving 128k for boot params() at: 81f5ff64 Stack Pointer at: 81f5ff48 Now running in RAM - U-Boot at: 83f90000 MMC: msc: 0 the manufacturer 1c SF: Detected EN25QH128A In: serial Out: serial Err: serial Net: ====>phy 0:0x0-0x0 found SPEED:0, DUPLEX:0 Jz4775-9161 upgradeFirmware 20200921120000 20200921120000 upgradeFirmware 20200921120000 20200921120000 upgradeFirmware 013 013 sdupdate - auto upgrade file from mmc to flash Usage: sdupdate LOAD_ID ADDR_START ADDR_END LOAD_ID: 0-->u-boot 1-->kernel 2-->rootfs 3-->demo.bin ex: sdupdate (update all) or sdupdate 0 0x0 0x40000 Enter key to stop autoboot in 3 seconds the manufacturer 1c SF: Detected EN25QH128A --->probe spend 4 ms SF: 2621440 bytes @ 0x50000 Read: OK --->read spend 842 ms ## Booting kernel from Legacy Image at 80600000 ... Image Name: Linux-3.10.14__isvp_swan_1.0__ Image Type: MIPS Linux Kernel Image (lzma compressed) Data Size: 1727656 Bytes = 1.6 MiB Load Address: 80010000 Entry Point: 803c7810 Verifying Checksum ... OK Uncompressing Kernel Image ... OK Starting kernel ...
现在的问题是,根据提示“Enter key to stop autoboot in 3 seconds”中断启动不成功,不管按什么键都会照常启动内核。ttl 连接确认没问题,是可以正常输入的。在内核启动开始跑 log 后按键会有一个登陆提示 Ingenic-uc1_1 login: 然后继续跑码。
我的疑惑是:
希望各位大佬解惑。
]]>有没有 v 站的大佬交流指导一下,这个方向的想法?
]]>但是作者没有在文章中透露细节,没办法,只有自己来研究。
准备了以下内容:
抓到的电源键广播包类似于:
/** * LEN | TYPE | VALUE * 2 | 0x01 | 0x04 * 3 | 0x03 | 0x1218 * 3 | 0x19 | 0x8001 * 13 | 0xFF | 0x5D000300011808642AA0C884 */ static uint8_t adv_data_on_off[] = { // Flags 0x02, 0x01, 0x04, // Complete list of 16-bit Service UUIDs 0x03, 0x03, 0x12, 0x18, // Appearance 0x03, 0x19, 0x80, 0x01, // Manufacturer Specific Data 0x0D, 0xFF, 0x5D, 0x00, 0x03, 0x00, 0x01, 0x18, 0x08, 0x64, 0x2A, 0xA0, 0xC8, 0x84 };
由于不知道怎么用手机重放测试,直接开始编写 ESP 代码,刷入之后,用小爱同学执行命令也能正常重放。 但是投影仪并没有反应。
观察遥控器广播的包数据 Manufacturer Specific Data
里,有一位是每次递增的。我直接改为下一次预计的值,重放之后也无法正常开关。
遥控器发出的包貌似是单次广播的?我看 BLE 协议里,广播包都是循环广播的?
按帖文里的说法,他直接重放原包就实现了,感觉我是不是哪里有问题。
现在卡住了,不知道后面如何进行。
我的代码放在 GitHub 了:esp32-ble-remote-control
希望各位能帮忙分析一下问题出在什么地方,谢谢
]]>目前发现,用 Arduino 框架,官方给的例程,可以正常搜索到其他 AP ,RSSI 值与旁边手机搜到的相近。但是无法创建 AP (软件认为已经成功创建,但用其他设备搜索不到),也无法连接其他 AP 。
例程:
https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi/examples/WiFiScan
https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi/examples/WiFiAccessPoint
用网络分析仪测试 Π 网络前的驻波比,在 2 左右。换过好多次芯片,天线和晶振也换过,不行。
相同的例程,用其他成品的 ESP32-C3 模组,能正常使用。
实在查不到资料,也不知道有啥论坛,不知道这里有没有高人,如果你有经验或者有信心帮我分析解决,我能以每小时 100 元的价格请你帮我做一对一指导。
]]>花了一晚上时间去移植。开发板主控 MCU 用的是 STM32F407VET6 ,I2C 接口用 I2C1 ,SCL 接 PB6 ,SDA 接 PB7 。
ESP_LOGI
间隔 163813
微秒,平均下来一次 float 计算要 1 微秒,与芯片性能严重不符。请问是什么原因导致的呢?#include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "esp_log.h" #define M2T(X) ((unsigned int)(X) / portTICK_PERIOD_MS) // ms to tick #include "esp_random.h" #include <sys/time.h> static const char *TAG = "main"; #define dataLen 14400 void makeMatrixUint8(uint8_t *buf, int len) { for (int i = 0; i < len; i++) { esp_fill_random(&buf[i], sizeof(uint8_t)); } } void makeMatrixFloat(float *buf, int len) { for (int i = 0; i < len; i++) { esp_fill_random(&buf[i], sizeof(float)); } } static void testTask() { uint8_t *testData1 = (uint8_t *)malloc(sizeof(uint8_t) * dataLen); float *testData2 = (float *)malloc(sizeof(float) * dataLen); struct timeval tv_d0; struct timeval tv_d1; while (1) { makeMatrixUint8(testData1, dataLen); makeMatrixFloat(testData2, dataLen); gettimeofday(&tv_d0, NULL); for (int t = 0; t < 10; t++) { for (int i = 0; i < dataLen; i++) { testData2[i] = testData1[i] * 0.3; } } gettimeofday(&tv_d1, NULL); ESP_LOGI(TAG, "%lu", 1000000 * (tv_d1.tv_sec - tv_d0.tv_sec) + (tv_d1.tv_usec - tv_d0.tv_usec)); vTaskDelay(1); } } void app_main() { xTaskCreate(testTask, "servoTask", 1024 * 4, NULL, tskIDLE_PRIORITY, NULL); }
]]>我买的是一个 esp32s3-n16r8 的开发板,板子上集成了一个 i2s 麦克风,我外接了一个 i2s 小功放并接了一个喇叭,运行 esp32 adf 官方语音唤醒识别示例 https://github.com/espressif/esp-adf/tree/master/examples/speech_recognition/wwe ,就是 master 分支代码,idf 版本是 4.4.1 。
但运行后,总是崩溃在 i2s_stream_init 函数,main 函数中 setup_player 和 start_recorder 里面都会调用这个函数,setup_player 先执行,调用没问题,start_recorder 中调用 i2s_stream_init 时单片机 reset 重启。
跟踪 i2s_stream_init 发现他会调用 heap_caps_malloc ,并且就在这里出问题,接下来的代码没有执行,s3 芯片是有外部 SPIRAN ,我都配置好了,并且 mem test 也显示 ok ,esp_get_free_heap_size 显示也有 8M 多可以用。
如果我把 setup_player 注释掉,只运行 start_recorder ,i2s_stream_init 可以成功,但也不太正常,几秒后也会崩溃,实在搞不清为什么了 :D
wx jhzzzz, qq 5488232
]]>不知道是不是因为过于底层…以前随便用的 Array.splice 在 c 上都要自己实现有点难受,当然这不是重点
屏幕( ILI94 什么来着)和触摸( GT911 )想找个文档难如登天,document 根本搜不出来,example 基本都不会给你解释为什么
LVGL 的文档也只会给你一堆 example 让你自己感受,我现在还没搞懂 imgbtn 的左中右 imgsrc 都是什么东西
相比之下乐鑫的文档还算比较翔实了…
Debug 感觉也不明不白,ESP32 debugger 只能搜出乐鑫的 ESP-IDF 调试环境,Arduino 就只能看别人的 tutorial 了。现在烧录前编译没检查出来的错误就只能直接板子崩溃(也看不到哪行代码造成的崩溃),再根据内核报错猜是哪里出了问题
性能优化就更玄学了,CPU 占用率就是上不去但 lvgl 的 fps 也不高。memcpy 开销应该也不大吧…搜到的结论说 struct 也不怎么吃性能。搜了半天怀疑是 TCP 拥塞控制算法的问题,准备禁用掉再战
周末虽然姑且把主要逻辑做完了,但真的好怀念 Web 开发所见即所得热重载周边生态完备轻松调试的开发环境
之前有楼主说人都往 Web 开发挤没人写嵌入式感觉就这开发环境活该没人(划掉)市场还是会用脚投票的
最后感谢一下 USBIP 这个项目,没这玩意我估计还得去学画 PCB 板(不)不过这玩意就是真的搜 document 都搜不出来的东西了,顺带让我学习了下 USBHID 通信和 c 的数据结构(笑)
]]>rock pi 5b 目前也没有个靠谱的渠道购买,我是想买来测一测能不能跑 fedora ,如果不能我还想 7 天无理由退货的,而且我还想找个支持 1 年保修的商家购买。
还有什么 arm 的设备比较适合拿来研究的?
]]>原来搞图像处理算法的, 大概两年前转到现在的 FPGA 的项目 主要搞 Xilinx 的驱动 /一部分 AI 算法的移植 /Gstreamer 的 Shell 一部分 WebAPP 的后端 Python/一部分前端的 Vue 什么的.
这个项目做了快两年, FPGA 入一点点门,但要自己去设定个逻辑什么的完全不知道怎么下手. 总觉得啥都不会, 出问题了就 Google, 运气好解决了好像也不知道原因. 请教各位大佬, FPGA/Linux 要怎么入门,感觉是个无底洞. 是不是该早点劝退.
]]>几个有特色的功能