ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
20 апреля
1326094
Связанные сообщения
Ch32V003ПолезноеRisc-V
нашел на китайской версии сайта WCH ннфографику про семество riscv ch32 - сделал картинку. теперь легче понять отличия. удобно ч...2023-12-11
VisionFive. SBC на RISC-V со встроенным GPU.2023-11-16
Я извиняюсь народ.) Но пролейте пожалуйста свет кто чем сейчас programmирует чипы на RISC-V?2023-11-07
[заработало] у кого есть удачный опыт "i2c заработало в ch32v003" ? промудохалсо весь выходной... выводы неоднозначные. может чт...2023-08-09
Пришел десяток CH32V003 в soic8 с Ali по 13 руб. Показались удобными для всяческой мелкой хренотени. Ну и как у китайцев положен...2023-07-26
СH32V203F8P6 - 96МГц. SPI - 12MГц, ENC28J60. Ping + UDP ping-pong 50 байт + UDP "спам" 1500 пак/сек. Вот такую вот картинку вижу...2023-07-03
Столько полезной информации...2023-07-03
Цука... CH32V00x с WCHlink нихт арбайтен. Требуют WCHlinkE. "Вот нахуя так делать? И, главное, зачем?"(С)... Да знаю, знаю зачем...2023-05-12
У ядра QingKeV4 есть расширенный набор коротких команд. Их пока только WCH-ный GCC порддерживает.2023-04-06
Траблы с WCH для CH32V203RBT6.2023-03-24
Risc-V, CH32V203RBT6, MounRiver Studio IDE, Си. Отладчик WCH-Link.2023-03-22
почитал доки на свежий китайский микроконтроллер ch32v307, есть много фич которые я воображал но не было в cortex-m. похоже risc...2023-03-03
Кто-нибудь уже пробовал использовать IAR EWARM для разработки под CH32F* от WCH? У производителя можно найти примеры и библиотек...2023-01-04
[RISC-V от WCH] - перспективно для замены всего недружественного. Klen, просьба покурить. ch32v103, ch32v307. - брать. Ес...2022-03-24
Платочки в формфакторе Raspberry Pi на RISC-V грядут. Заметим, сразу идет bare metal ПО, FreeRTOS, и на картинке видим ChipLink....2021-12-01
Allwinner обещается в этом году выкатить жЫрный RISC-V2021-02-09
ну давай Муська! еще капельку!: поразгонял gd32vf103cb + oled 0.962020-05-31
есть 3 реле, и надо чтобы только одно реле гарантированно открывалось в один момент времени. то есть если оно залипло или по оши...2020-05-26
gd32vf103: выполнил обезжиривание кода rv-link/longan-nano, пришлось переделывать китайский код. меня попросили дать бинарь для ...2020-04-26
кто нибудь знает? GigaDevice планирует в gd32vf всунуть FPU или еще что нибудь, нигде не нашел их планов по захвату поляны - я б...2020-02-12
Computer Organization and Design RISC-V edition. просто бесподобны мануаЛЬ!2019-11-30
gd32vf103: Думаю можно подумать открывать новый раздел - RISCV2019-10-28
Китайцкая GigaDevice залепила мелкокристаллку на RISC-V. 108Mhz, 128K Flash, 32K RAM. На замену STM32F103, вроде как совместима ...2019-08-31
[RISC-V: ядра, SoC для микропроцессоров и микроконтроллеров] Сводный системный топик.2018-12-04
[RISC-V как предел софткорного процессоростроения]. Текущие результаты капиталистического соревнования.2018-04-28
[Сводный топик про RISC-V] Гнездо архитектуры -> -->2017-08-11
klen (01.07.2023 02:44 - 09.01.2024 17:13, просмотров: 15416)
[09.01.2024] по ходу подпрыгивании на тему "подъема-взлета" ch32v003 всунул в него CoreMark. промерил... 

на данный момент

1. допортил gcc на поддержку ядра qkv2a ( оптимизация под набор инструкций и добавка генерации обычных прерываний и "лысых" когда включена аппаратное двухуровневое сохранение)

2. допили свой sdk до состояния: интерфейс к ядру + fpic + systick + rcc. осталось остальную переферию обернуть. ее немного в этих микросхемках. может за выходные половинку сделаю.

3. ядро ricsv32ec - тоесть урезанное до 16 штук регистры и к сожалению отсутствует умножитель. если бы он был.... думаю результат в полтора раза больше был бы? побыстрее stm32l0xx c cortex-m0plus

4 на прогоне CoreMark потребление - 6.0 мА при 5В питания.

5. всунул CoreMark для тестирования сравнения. вывод результата через uart на консоль хост машины. получилось 94,914 баллов. которые равны числу итераций в секунду.


этот результат позволяет заключить что микросхемка по мнению СoreMark эквивалентна stm32f0xx .





размер прошивочки


memutz .././../out/image.elf 16K 2K
section info:
sec name size increase[%]
  .text 11180 0 (0.000000%)
  .data 24 0 (0.000000%)
  .bss 1024 0 (0.000000%)
utilization:
  ram : 51.1719% 0 (0.000000%)
  flash: 68.3838% 0 (0.000000%)

вот если кому интересно что генерится из чего - интермикс исходного кода и асма этой прошивки. кстате - обратите внимание, objdump научился зачем то показывать трассы переходов :) прикольненько

image.lss


первые выводы - оно работает. явных косяков покане обнаружил.

аппаратное сохранение контекста - гожая метода, почему нельзя сделать глубину хотя бы 8. и делать везде и всегда? 8*16(32) *4 байтов скрытого СОЗУ пожалели?

вход в прерывание аж тремя способами - в таблице адреса перехода, инструкция перехода и VFT-метод

"релаксация" на линковке дает -5..15% уменьшения кода и столько же его же ускорения. кто не в курсе - механизм релакса - способ сжать инструкции по адресным полям используя регистр gp процессоров RISCV. обращения к адресам в диапазоне +-2К от значения хранящегося в регистре gp требует на одну иструкцию вычисления адреса меньше. это 30 процентов от всего кода обращения.

вот тот же код но с выключенной релаксной оптимизацией на ликовке

image.lss

memutz .././../out/image.elf 16K 2K
section info:
sec name size increase[%]
  .text 12160 980 (8.765650%)
  .data 24 0 (0.000000%)
  .bss 1024 0 (0.000000%)
utilization:
  ram : 51.1719% 0 (0.000000%)
  flash: 74.3652% 980 (8.746874%)

на круг при размере кода 11Kb использование этого трюка сократило код на 980 байт, это почти 10%.



вот красноречивый пример как это работает на примере обработчика прерывания sys_tick - в нем сбрасывается флаг переполнения и инкрементируется счеткик миллисикекуд для измерения времени теста


с релаксом

00000230 <ch32v00x::sys_tick_irq_handler()>:
  void __ai__ val( const T v) { NRO *(((volatile T*)this))  = v; }
     230:	e000f7b7          	lui	a5,0xe000f
     234:	0007a223          	sw	zero,4(a5) # e000f004 <__stack_end__+0xc000e804>
namespace ch32v00x
{
   irq_handler_hpei(sys_tick)
    {
        sys_tick.compare_flag_clear();
        tick_count = tick_count + 1 ;
     238:	e181a283          	lw	t0,-488(gp) # 20000018 <tick_count>
     23c:	00128313          	add	t1,t0,1
     240:	e061ac23          	sw	t1,-488(gp) # 20000018 <tick_count>
    }
     244:	30200073          	mret

без релакса


0000025e <ch32v00x::sys_tick_irq_handler()>:
  void __ai__ val( const T v) { NRO *(((volatile T*)this))  = v; }
     25e:	e000f7b7          	lui	a5,0xe000f
     262:	0007a223          	sw	zero,4(a5) # e000f004 <__stack_end__+0xc000e804>
namespace ch32v00x
{
   irq_handler_hpei(sys_tick)
    {
        sys_tick.compare_flag_clear();
        tick_count = tick_count + 1 ;
     266:	20000737          	lui	a4,0x20000
     26a:	01872283          	lw	t0,24(a4) # 20000018 <tick_count>
     26e:	00128313          	add	t1,t0,1
     272:	00672c23          	sw	t1,24(a4)
    }
     276:	30200073          	mret

я потратил время разобраться как это работает, научился компиллеру объяснять и он с радостью оптимизирует код.

если понадобится - разжую. сам не сразу понял как это заставить работать.

беглым признаком что ваш компиллер и линкер умеют это делать - наличие в коде на каждом углу вычисление адресов через регистр gp, например так:

lw t0,-488(gp) # 20000018 <tick_count>


в приведенных выше image.lss это очень хорошо видно. во втором гораздо больше калорий тратится на вычисление адресов в лоб, в первом через относительный адрес используя gp.


пока что из недостатоков только отсутствие целочисленного перемножителя и делителя в процессоре


ну как то так.. за 128 рулей просто замечательно.

китайцы сдирают микросхемы с буржуев. а я сильно думаю содрать с китайцев


[обновление 2.07.23]

доковырял rrc - есть новые сведения.. минус две микросхемы

1. есть засада о которой нужно знать. при использовании кварцевого генератора hse нужно перед его запуском замапить пины gpioa_pin1 gpioa_pin2 на генератор. иначе они как и положено просто gpioa. второе - выставить латентность wait1 (это не точно), и только потом запускать hse.

я писал код с нуля и это поздно понял. две микросхемы ушли в астрал, такое ощущение что если не проверить что генератор не запустился и воткнуть источник sys_clock: hsi -> hse то все встает колом... включая отладочный интерфейс. отладчик говорит что нет связи с микросхемами. это все можно понять и даже простить ... но засада в том что как я понял нет пина BOOT0 как в stm32 и теперь невозможно запустится встроенным загрузчиком :( жопа. остается просверлить дыру в микросхеме и иголкой дать клок чтоб ее стереть. пока я не нашел выхода из этой ситуации. на форумах забугорных примерно такой же плач Жорославны о том что сожрала торт и лопнули.

2. если первое есть засада в котору не нужно вступать как в партию... то теперь наверно говнеццо которое не вынести лопатой - работа hsi и pll. ниже картинки джиттера клоков:

отстройка по времени от захваченного триггером фронта 10мкс

клок от hsi 24МГц


клок от hse 24МГц


клок от hsi->pll(x2) 48МГц


клок от hse->pll(x2) 48МГц



какие мы можем сделать предварительные выводы - hsi гамно.... ну сильно он дрожит, похоже не стали они делать аналоговый RC генератор а обошлись чем то на триггерах у которых порог не сильно стабильный. это можно понять и простить. но UART может на большой скорости и не разработать - лагать битами. нужно проверить. как и положено характеристики hse определяются в основном внешним резонатором, но наверно фазового шума тут по выше озвученной теории до хрена. модули которые не чувствительны к фазовому шуму как UART должны работать на любой скорости.

а вот pll меня убила - выход дрожит как ... слов нет без мата. из чего у меня гепотеза - а нет у них никаого ФАПЧ!!! эти мошенники тупо умножают частоту на фронтах без фапч. а пишуn в доках pll - тому что у всех в этом месте документации и микросхемы есть pll! хотя я уже не уверен что у всех в микросхеме. в доках что угодно можно писать.

то есть по предварительным наблюдениям если работать не от кварца напрямую от hse а от pll то смысла ставить кварц нету, любой говнорезанатор за 3 копейки. а по сути можно сразу hsi->pll теже яйца выйдут но без деталек.

если кто то, найдет ошибки в моих интерпретациях наблюдений я буду рад. вдруг не все так плох0 с клоками.


[обновление 2.07.23+]

интересный резултата - при работе hse->pll как мы выяснили фапч хрипит (картинка выше). как следует из документации на частоте системного клока более 24МГц нужно выставлять для флеша wait1 чтобы она успевалапроцу выдавать команды. но! ели на это положить болт и выставить wait0 то почемуто клок с выхода фапча становится намного чище!



если посмотреть на схемку rcc




меня лично напрягает что на флеш отдается 1/3 частоты от чего (в данном случае отхрипящего hsi ) это как минимум настораживает на тему а как они там синхронизацию выборки команд проца и буффера шины команд флеша делают?

все мутно но хотябы воспроизводимо на отдельно взятой микросхеме.

однакл жеж получается на 48МГц хорошего синтеза частот и временных интервалов таймерами может не получится... пока видится только от hse без фапча на 24МГц..


поробывал проверить работу на 48МГц wait0 - не начнет ли глючит? нет не начало, uart работает, тест CoreMark проходит без ошибок с укорением с 94,914 до 122,67 баллов. в таком виде riscv обходит cortex-m0plus(у которого есть инструкция умножения)




дожал! заработало LTO

memutz .././../out/image.elf 16K 2K  
section info:
	sec name	size		increase[%]
	.text		14092		-1468 (-9.434450%)
	.data		40			0 (0.000000%)
	.bss		1016		0 (0.000000%)
utilization:
	ram  :		51.5625%	0 (0.000000%)
	flash:		86.2549%	-1468 (-9.410256%)

LTO оптимизатор пожал код почти на 10%. также вырасла скорость кода. теперь 96.06 / 124.83 балов против 94.91/122.67 без LTO, скрость увеличиласьне не много - 90% кода это сраный printf, не вычислительный код, вот его и пожал оптимизатор, к сожалению по соглашению править core_main.c нельзя. а он в нем. но размер прошивки под притык. поэтому LTO тут как нельзя здорово подходить для решения проблемы малого размера флеша.




сегодня протянул в коде таймеры, запустил.

удивительное в решете! выходы таймеров не дрожат. похоже с фапчем и клоками все в порядке, но почему mco выход такой дрожащий?

так что страхи по поводу плохих клоков временно отменяются.


[09.07.23]

обнаружена масса ошибок в рефмануале. в даташит не всматриволся. видно что копипастили возможно с v2xx или v3xx, переферия имеет добавки по сравнению с ними.

переферия dbgmcu описана в рефе неправильно и в коде pal тоже. поэтому не расчитывайте остановить таймеры при отладке если будете пользоватся фирменной библой. они на 8 бит влево промазали в регистре. регистр к моему удивлению расположен в процессоре! сsr 0x7c0.

afio exti dma tim работают пока идентично stm32fxxx, по крайней мере так выглядит, эрраты мы так пока еще и невидели, и в глубокие подвалы не заглядывали.


[14.07.2023]

написал тест измерения скорости входа выход в обработчик прерывания. вложенные прерывания и аппаратное сохранение контекста включено, обработчик собран с расчетом на это(эпилог и пролог не генерятся)

код цикла генерящего прерывания:

#include "appdefs.h"
static constexpr string_view hellow = "hellow from irq enty speed test demo!\n\n" ; int main(void) { cout < cout_t::vt100_t::yellow < hellow <= cout_t::vt100_t::white ; cout < "0. config afio exti line6 <- gpiod" <= dendl ; afio.clock_enable(); afio.exti6_gpiod(); cout < "1. config gpiod pin5 pin6" <= dendl ; gpiod.clock_enable(); gpiod.pin6_mode_output_50mhz(); gpiod.pin6_output_type_push_pull(); gpiod.pin6_reset(); gpiod.pin5_mode_output_50mhz(); gpiod.pin5_output_type_push_pull(); gpiod.pin5_reset(); cout < "3. config exti line6 fall edge" <= dendl ; exti.line6_interrupt_enable(); exti.line6_rise_edge_enable(); exti.pfic_enable(); while(1) { gpiod.pin6_set(); while ( (gpiod.output & gpio_t::b6 )) {} exti.line6_software_interrupt_event_generate(); while ( bool(exti.line6_interrupt_flag()) ) {} } } namespace ch32v00x { irq_handler_hpei(exti7_0) { gpiod.pin5_set(); exti.line6_interrupt_flag_clear(); gpiod.pin5_reset(); gpiod.pin6_reset(); } }



асм непоследственно цикла и обработчика



     45c:	/----> c88c                	sw	a1,16(s1)
      while ( (gpiod.output & gpio_t::b6 )) {}
     45e:	|  /-> 00c4a083          	lw	ra,12(s1)
     462:	|  |   0400f413          	and	s0,ra,64
     466:	|  \-- fc65                	bnez	s0,45e <__firmware_build_time__+0x34>
     468:	|      cb94                	sw	a3,16(a5)
  template <typename U> __ai__ auto rd2()                    const { NRO return static_cast<U>(((*((volatile T*)this)) >> ((const T)U::offset)) & ((const T)U::mask)) ; }
     46a:	|  /-> 0147a283          	lw	t0,20(a5)
      while ( bool(exti.line6_interrupt_flag()) ) {}
     46e:	|  |   0402f713          	and	a4,t0,64
     472:	|  \-- ff65                	bnez	a4,46a <__firmware_build_time__+0x40>
     474:	\----- b7e5                	j	45c <__firmware_build_time__+0x32>


00000156 <ch32v00x::exti7_0_irq_handler()>:
{
  gpiod.pin5_set();      
156: 400117b7 lui a5,0x40011 15a: 40078293 add t0,a5,1024 # 40011400 <__stack_end__+0x20010c00> 15e: 02000713 li a4,32 162: 00e2a823 sw a4,16(t0)
exti.line6_interrupt_flag_clear(); 166: 40010337 lui t1,0x40010 16a: 40030393 add t2,t1,1024 # 40010400 <__stack_end__+0x2000fc00> 16e: 04000693 li a3,64 172: 00d3aa23 sw a3,20(t2)
gpiod.pin5_reset(); 176: 00200537 lui a0,0x200 17a: 00a2a823 sw a0,16(t0)
gpiod.pin6_reset(); 17e: 004005b7 lui a1,0x400 182: 00b2a823 sw a1,16(t0) } 186: 30200073 mret


gpiod pin6 фиолетовый

gpiod pin5 желтый

mco(sys_clock) синий




чето както очено вяло. на заходе в обработчик процессор еще отмораживается на 23 такта sys_clock. в итоге порядка 480нс... есть подозрения что он сохраняет 10 "Caller Saved" регистров .. в ОЗУ




как раз по два такта на обмен по шине с ОЗУ + сохранене указателя стека. но позвольте. мы то наивно полагали что оно будет сохранять все регистры парралельно в внутрение потроха ядра за ОДИН такт...

иначе мне не вдулось это HPE китайского производства. кто то тут жаловался на 100нс, я и того в четыре раза больше получил. елочные гирлянды да, а вот моторы нет - сгорят с такой реакцийей на КЗ к херам собачьим. это пол микросекунды, а микросекнда по нашим представлениям это вечность - медь превращается в пар. пар в плазму, плазма в черныю дыру посередине изделия засасывающую в себя источник энергии.


[обновление 13.08.23]

как было написано в шапке - две платки были окирпичены выбором hse который я не включил. сегодня подал 8 мгц на pa1 - отладчик смог почистить флешь. вывод. мжно написать программу такую что оставить процессор без клока. но удалось затактировать снаружи и спасти две микросхемки.


[29.107.2023]

Внезапно чудесный dma..

протрахался вчера и сегодня... оказываеццо бит канала dma EN не сбрасывается при окончании передачи и обнулении счетчика транзакций СNTR. это происходит только при ошибке. тоесть не так как в STM32, сбрасывать нужно ручками! если не сбросить то в в сh32v307 записать новый адрес памяти не дает, а в ch32v003 дает! баги это или фичи хрен его знает - при переносе кода с 003 на 307 вылезно это потому как код не заработал... а обесчалось по документации что модули одинаковые.

одним словом не такие как у STM32 да еще промеж себя отличаются. все это не криминально, но из док этого нифига не видно. эрраты нет. приходится на пузе проползать по всему этому болотцу. но в итоге работает. дальше поробую поднять usb и сеть. посмотрим сколько мозка этот эксперимент высосет. сегодняшний результат - экранчики oled 0.96 (ssd1306) подро работают на 1.23МГц I2C параллелно с eeprom FT24C64A. время обновления картинки 8.3мс. отрисованный фрембуфер качается в ssd1306 асихронно по средством dma.


[09.01.2024] обнаружил новое чудесатое

в обоих микроконтроллерах v003(ядро qkv2a) и v307(ядро qkv4f) в ядрах реализован системный таймер SysTick, причем в qkv2a каcтрированый по разрядности. так вот, в ядрах есть специальный регистр dcsr(адрес 0x7b0) в котором девятый бит включает останов таймера при отанове процессорав во время отладки. так вот в v307 это работает, в v003 не работает, ошибка в ревизии микросхемы или что еще, не знаю но в дока для обоих написано rw