- 2023-09-28
-
发表了主题帖:
树莓派5要来了
在经历了几年全球供应链困境导致 Raspberry Pi 单板计算机的产能降低和零售价格上涨之后,今天终于迎来了更新。Raspberry Pi 4 上市四年后,今天Raspberry Pi 5正式发布!新推出的 Raspberry Pi 5 配备了经过大幅改进升级的SoC,带来了显著的性能提升。
Raspberry Pi 5 将于 10 月底推出。4GB 型号的售价为 60 美元,8GB 版本的售价为 80 美元,比普通 Raspberry Pi 4 的定价上涨了 5 美元,但几乎该平台的各个方面都进行了升级。
Raspberry Pi 5带来更多令人兴奋的功能和性能,让我们一起来看看它都带来了哪些新特性吧。
更强大的性能
主要特点包括:
2.4GHz 四核 64 位 Arm Cortex-A76 CPU
VideoCore VII GPU,支持OpenGL ES 3.1、Vulkan 1.2
双 4Kp60 HDMI® 显示输出
4Kp60 HEVC 解码器
双频 802.11ac Wi-Fi®
蓝牙 5.0 / 蓝牙低功耗 (BLE)
支持 SDR104 模式的高速 microSD 卡接口
2个USB 3.0端口,支持同时5Gbps运行
2 个 USB 2.0 端口
千兆位以太网,支持 PoE+(需要单独的 PoE+ HAT,即将推出)
2 × 4 通道 MIPI 摄像头/显示收发器
PCIe 2.0 x1 接口,用于快速外设
Raspberry Pi 标准 40 针 GPIO 接头
实时时钟
电源按钮
Raspberry Pi 5 的设计目标是比 Raspberry Pi 4 提供 2~3 倍的性能提升。Raspberry Pi 5搭载了全新的四核ARM Cortex-A76 CPU,主频高达 2.4GHz,而Raspberry Pi 4 的主频仅为 1.8GHz。图形也得到了很大改进,现在 Raspberry Pi 4 的 VideoCore VI 图形处理器配备了 800MHz VideoCore VII 图形处理器。而Raspberry Pi 5 能够驱动两个 4K @ 60Hz 显示器,并具有 4K @ 60 HEVC 解码硬件功能。这一升级使得它在性能方面相较于上一代产品有了质的飞跃。
不仅如此,GPU也得到了升级,采用了最新的Mali-G77 GPU,为图形性能提供了巨大的提升。这意味着你可以更流畅地运行各种应用程序,包括高清视频播放和3D游戏。
新平台,新芯片组
Raspberry Pi 5有三款新芯片,搭配起来,性能简直飞起!
BCM2712
BCM2712 是 Broadcom 的一款新型 16 纳米应用处理器 (AP),源自为 Raspberry Pi 4 提供动力的 28 纳米 BCM2711 AP,并具有众多架构增强功能。新的内核、更高的时钟速度和更小的工艺几何尺寸的结合产生了速度更快的 Raspberry Pi,并且在给定工作负载下消耗的功率要少得多。
RP1
RP1 是针对 Raspberry Pi 5 的 I/O 控制器,由 Raspberry Pi 中提供 RP2040 微控制器的同一团队设计,并与 RP2040 一样,在 TSMC 成熟的 40LP 工艺上实现。提供2个USB 3.0和2个USB 2.0接口;千兆位以太网控制器;两个用于摄像头和显示器的四通道 MIPI 收发器;模拟视频输出;3.3V通用I/O(GPIO);以及常见的 GPIO 复用低速接口(UART、SPI、I2C、I2S 和 PWM)集合。四通道 PCI Express 2.0 接口提供返回 BCM2712 的 16Gb/s 链路。
前几代 Raspberry Pi 构建在单片AP 架构上:而一些外围功能由外部设备提供,基本上所有 I/O 功能都集成到 AP 本身中。Raspberry Pi 5 基于分解的小芯片架构构建。在这里,AP 只提供主要的快速数字功能、SD 卡接口(出于电路板布局原因)和最快的接口(SDRAM、HDMI 和 PCI Express)。所有其他 I/O 功能都被卸载到单独的 I/O 控制器,在较旧、更便宜的流程节点上实现,并通过 PCI Express 连接到 AP。
DA9091
BCM2712 和 RP1 由芯片组的第三个新组件瑞萨 DA9091“Gilmour”电源管理 IC (PMIC) 支持。它集成了八个独立的开关模式电源,以生成电路板所需的各种电压,其中包括一个四相核心电源,能够提供 20 安培的电流,为 Cortex-A76 核心和 BCM2712 中的其他数字逻辑供电。
更大的内存
Raspberry Pi 5最高配备了8GB LPDDR4内存,这使得它在多任务处理和大型应用程序运行方面表现出色。无论是进行编程开发、虚拟机运行还是数据处理,Raspberry Pi 5都能轻松胜任。
更快的存储
为了提供更快的存储性能,Raspberry Pi 5采用了PCIe 2.0接口,这意味着你可以连接高速NVMe固态硬盘,实现极快的数据传输速度。不再需要等待文件加载,你可以更快地启动应用程序和访问数据。
- 2023-09-27
-
回复了主题帖:
技术圈子里很多现象其实就是叶公好龙
以前都用的破解AD,后来公司上市了,不让用了,就改为kicad 和破解 PADS了
- 2023-09-05
-
加入了学习《ARM Cortex-M0 全可编程SoC原理及实现》,观看 Cortex-M0课程导学
-
加入了学习《一块PCB板的生产过程》,观看 一块PCB板的生产过程
- 2023-08-23
-
发表了主题帖:
今天遇到的问题:任务堆栈没给够所以死机
问题1::
创建一个任务,UDP 发送数据用的,给了256字节堆栈,然后就死机了,改为1024问题解决。
问题2:
UDP 绑定本地端口写法,注意IP地址用IPADDR_ANY, 源代码用的 #define IPADDR_LOOPBACK ((u32_t)0x7f000001UL)不太行,改为IPADDR_ANY
memset(&src, 0, sizeof(struct sockaddr_in));
src.sin_family = AF_INET;
src.sin_addr.s_addr = htonl(IPADDR_ANY);
src.sin_port = htons(NETLOG_PORT_BIND);
if(bind(sendFd, (struct sockaddr *)&src, sizeof(struct sockaddr_in)) != 0)
{
close(sendFd);
return;
}
- 2023-07-31
-
发表了主题帖:
TCP 的 send 函数返回OK,是收到了对方的ACK才返回OK,还是仅仅发出去了?
问题1:
TCP 的 send 函数返回OK,是收到了对方的ACK才返回OK,
还是仅仅保证本身发出去了,但是不保证对方是否收到?
问题2:
在lwip 发送函数中,数据发出了之后,怎么查询对方接收到了呢
lwip_send(int s, const void *data, size_t size, int flags)
- 2023-07-18
-
发表了主题帖:
稳恒科技4G模组 WH-G405tf 模组学习笔记
1. LTE模组
移动,联通,电信 4G 高速接入,同时支持移动和联通 3G 与 2G 接入
主要功能是透传,2路 socket
2. 支持协议 TCP/UDP/HTTP/DNS/FTP
3. 工作模式有3种
网络透传模式:数据通过模块串口直接发送到网络服务器,不做任何处理和修改。
HTTPD Client:数据通过串口进入模块后,经过 httpd 协议封装后,在发往 http 服务器。
UDC 透传:数据通过串口进入模块后,经过 UDC 协议封装后,发向服务器。
UDC模式是有人自己定制的协议,协议是什么?好处是什么?
4. 遇到一个问题
这个模组透传模式 socket A和B同时开,怎么区分A和B 的数据
模块能够远程OTA升级模块本身,怎么升级?什么协议,什么服务器?什么流程?
-
发表了日志:
稳恒科技4G模组 WH-G405tf 模组学习笔记
- 2023-07-12
-
发表了主题帖:
紫光展锐 8850芯片调试 LittleVGL 图形
1. 初步调试OK,只写了个最简单的文字标签,使用的屏 ST7735S, 1.8寸,接下来可以搞点复杂的界面了
-
发表了日志:
紫光展锐 8850芯片调试 LittleVGL 图形
- 2023-06-27
-
回复了主题帖:
cmake的 target_sources 用法 求助
bigbat 发表于 2023-6-27 10:09
有使用aux_source_directory语句,可以搜索指定目录下的所有源文件,也可以使用
file(GLOB SRC_LIST ${P ...
谢谢,我使用了 FILE 这个
set(target littlevgl0)
add_app_libraries($<TARGET_FILE:${target}>)
set(LVGL_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR})
file(GLOB_RECURSE SOURCES ${LVGL_ROOT_DIR}/src/*.c ${LVGL_ROOT_DIR}/porting/*.c)
add_library(target ${SOURCES})
-
发表了主题帖:
cmake的 target_sources 用法 求助
cmake的 target_sources 用法
是包含需要的 .c 文件,有没有什么办法直接包含某个文件夹里面的所有文件,语法怎么写的
目前我是一个个 .c 写上去的,比较麻烦
target_sources(${target} PRIVATE
src/ftp_utils.c
src/ftp_protocol.c
src/ftp_connection.c
)
- 2023-06-14
-
回复了主题帖:
RT-thread 创建任务 学习(2)记录遇到一个着实看不懂的代码
wangerxian 发表于 2023-6-14 11:09
封装这么多层,应该是为了让代码更好移植且更安全。
这么解释有道理
-
回复了主题帖:
移芯NB-IOT 的 GPIO学习笔记1
秦天qintian0303 发表于 2023-6-14 11:16
你的这个睡眠是模块睡眠还是网络睡眠?NB网络的一大特点就是有PSM模式
PSM 和 同时进入处理器低功耗
-
发表了主题帖:
RT-thread 创建任务 学习(2)记录遇到一个着实看不懂的代码
任务创建中,首先要初始化,那做了哪些工作? 主要是这个函数_thread_init 具体实现分析下
记录遇到一个着实看不懂的代码(见第7)
1. 初始化链表
rt_list_init(&(thread->tlist));
这个链表有意思,用这个链表把一个个任务放在一个链表里面
struct rt_list_node
{
struct rt_list_node *next; /**< point to next node. */
struct rt_list_node *prev; /**< point to prev node. */
};
2. 把任务的入口函数,参数,地址和大小赋值给任务控制块
thread->entry = (void *)entry;
thread->parameter = parameter;
/* stack init */
thread->stack_addr = stack_start;
thread->stack_size = stack_size;
/* init thread stack */
rt_memset(thread->stack_addr, '#', thread->stack_size);
3. 任务栈指针的处理,待研究
thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter,
(rt_uint8_t *)((char *)thread->stack_addr + thread->stack_size - sizeof(rt_ubase_t)),
(void *)_thread_exit);
4. 任务优先级
thread->init_priority = priority;
thread->current_priority = priority;
thread->number_mask = 0;
5. 任务的tick,这个什么用途?tick is the time slice if there are same priority thread,如果有相同优先级
thread->init_tick = tick;
thread->remaining_tick = tick;
6. 初始化定时器,这个定时器有啥用途呢?
rt_timer_init(&(thread->thread_timer),
thread->name,
_thread_timeout,
thread,
0,
RT_TIMER_FLAG_ONE_SHOT);
7. RT_OBJECT_HOOK_CALL(rt_thread_inited_hook, (thread)); 是什么意思?初始化钩子函数
根据以下代码
static void (*rt_thread_inited_hook) (rt_thread_t thread);
#define RT_OBJECT_HOOK_CALL(func, argv) __on_##func argv
组合成 __on_rt_thread_inited_hook(thread),初始化钩子函数
果然,之后找到原文
#ifndef __on_rt_thread_inited_hook
#define __on_rt_thread_inited_hook(thread) __ON_HOOK_ARGS(rt_thread_inited_hook, (thread))
#endif
往下继续找宏定义
define __ON_HOOK_ARGS(__hook, argv) do {if ((__hook) != RT_NULL) __hook argv; } while (0)
怎么感觉绕了一大圈,绕不懂了,搞这么复杂干啥,我就很不懂啊,按照我的理解,直接写成下面的不好吗
#define RT_OBJECT_HOOK_CALL(func, argv) do {if ((func) != RT_NULL) func argv; } while (0)
-
发表了日志:
RT-thread 创建任务 学习(2)记录遇到一个着实看不懂的代码
- 2023-06-13
-
发表了主题帖:
RT-thread 创建任务 学习(1)
本帖最后由 乔海权 于 2023-6-13 18:03 编辑
创建任务
1. 先搞个任务的栈,ID值
static rt_uint8_t thread_stack[512];
struct rt_thread at_task_id = {0};
2. 在 hal_entry.c 里面创建任务, at_task_handler 是个函数指针,就感觉离谱叫函数指针
void hal_entry(void)
{
rt_kprintf("\nHello RT-Thread!\n");
// 创建任务1
rt_thread_init(&at_task_id, "at_task", at_task_handler, RT_NULL, thread_stack, 512, 25, 5);
rt_thread_startup(&at_task_id);
while (1)
{
rt_thread_mdelay(500);
}
}
3. 任务的执行函数
void at_task_handler(void *param)
{
while(1)
{
rt_pin_write(LED_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
}
4. 以上就是添加新任务的功能
5. 创建一个任务做了什么,大致找了一下,跟任务相关的数据放在这个结构体里面
struct rt_thread at_task_id = {0};
阅读代码
struct rt_thread
{
/* rt object */
#if RT_NAME_MAX > 0
char name[RT_NAME_MAX]; // 内核组件的名字,内核组件包括 线程,信号量,队列等
#else
const char *name; /**< static name of kernel object */
#endif /* RT_NAME_MAX > 0 */
rt_uint8_t type; // 内核组件的类型
rt_uint8_t flags; // 内核组件的标志位
rt_list_t list; //组件列表
rt_list_t tlist; // 线程列表
/* stack point and entry */
void *sp; // 栈指针
void *entry; // 线程的实际运行函数
void *parameter; // 线程参数
void *stack_addr; //栈地址
rt_uint32_t stack_size; // 栈大小
/* error code */
rt_err_t error; /**< error code */
rt_uint8_t stat; //线程状态
/* priority */
rt_uint8_t current_priority; /**< current priority */ //当前优先级
rt_uint8_t init_priority; /**< initialized priority */ // 初始化的优先级
rt_uint32_t number_mask; /**< priority number mask */ //优先级掩码
#ifdef RT_USING_MUTEX // 如果使用互斥锁
/* object for IPC */
rt_list_t taken_object_list;
rt_object_t pending_object;
#endif
#ifdef RT_USING_EVENT //如果使用事件
/* thread event */
rt_uint32_t event_set;
rt_uint8_t event_info;
#endif /* RT_USING_EVENT */
#ifdef RT_USING_SIGNALS //如果使用信号量
rt_sigset_t sig_pending; /**< the pending signals */
rt_sigset_t sig_mask; /**< the mask bits of signal */
#ifndef RT_USING_SMP
void *sig_ret; /**< the return stack pointer from signal */
#endif /* RT_USING_SMP */
rt_sighandler_t *sig_vectors; /**< vectors of signal handler */
void *si_list; /**< the signal infor list */
#endif /* RT_USING_SIGNALS */
rt_ubase_t init_tick; /**< thread's initialized tick */ // 线程初始的时间线
rt_ubase_t remaining_tick; /**< remaining tick */
struct rt_timer thread_timer; /**< built-in thread timer */ //定时器相关
void (*cleanup)(struct rt_thread *tid); /**< cleanup function when thread exit */ //任务退出时的清除函数
/* light weight process if present */
rt_ubase_t user_data; /**< private user data beyond this thread */
};
typedef struct rt_thread *rt_thread_t;
-
发表了日志:
RT-studio 创建任务 学习(1)
- 2023-06-12
-
发表了主题帖:
移芯NB-IOT 的 GPIO学习笔记1
1. GPIO 分为 普通的, AON_GPIO
2. 普通的 电平,外部引脚控制 IO_1833_SEL 引脚选择:浮空为 1.8V,接地为 3.3V。但是实际是一个范围
其中硬件选择1.8V 时,可以配置电压范围,1.65V~3.00V, 选择3.3V 时,可以配置电压范围,2.65V~3.40V
配置用的函数 void slpManNormalIOVoltSet(IOVoltageSel_t sel)
3. 下面这句话 ,我理解是在睡眠后,原来软件配置的电压会自动变成接近的 1.8V/2.8V/3.2V ???
在睡眠后,普通 IO 的电平会根据硬件选择,及软件配置。恢复为 1.8V/2.8V/3.2V。
如原本选择 1.75V,则唤醒后恢复成 1.8V。如原本选择 3.4V,则唤醒后恢复成 3.2V。
4. AON_GPIO 就是掉电后,电平还可以保持
slpManAONIOPowerOn()接口给 AON_GPIO 上电后,默认电压是 1.8V。
5. 设置例程
(1)使能电源slpManAONIOPowerOn(), 普通 GPIO不需要
(2)配置这个引脚 复用成AON_GPIO, PAD_SetPinConfig
(3)配置输入输出,输出高电平或低电平,输入中断是否开启,中断是边沿还是电平触发等。GPIO_PinConfig
-
发表了日志:
移芯NB-IOT 的 GPIO学习笔记1